2020年11月19日

C++11以降の未使用の関数引数の書き方

GCC でコンパイル時に -Wall -Wextra の 2 オプションを付けるというのは非常に一般的です。この場合、以下のように未使用の関数引数には警告が出ます。
$ cat test.c
void f(int x) {}
void g(int x) {}

int main()
{
    f(10);
    g(10);
    return 0;
}

$ gcc -Wall -Wextra test.c
test.c: In function ‘f’:
test.c:1:12: warning: unused parameter ‘x’ [-Wunused-parameter]
 void f(int x) {}
            ^
test.c: In function ‘g’:
test.c:2:12: warning: unused parameter ‘x’ [-Wunused-parameter]
 void g(int x) {}
            ^
しかし、例えばコールバックとして渡す関数(ハンドラ)のように、引数を全部使わない関数というのはよくあります。



C の場合は、GCC の attribute を使うか、(void) にキャストするという方法が一般的ですが面倒です。
$ cat test2.c
void f(__attribute__((unused)) int x) {}
void g(int x) { (void)x; }

int main()
{
    f(10);
    g(10);
    return 0;
}

$ gcc -Wall -Wextra test2.c
C++ の場合ならば、C++11 以降、コンパイラ拡張ではなく、正式な仕様で未使用引数の名前を省略するという書き方が許されました。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf
8.4 Function definitions
8.4.1 In general

6 [ Note: Unused parameters need not be named. For example,
void print(int a, int) {
  std::printf("a = %d\n",a);
}
end note ]
しかしこれ、GCC でも Clang でも、C++98 や C++03 でも通ってしまいます。
$ cat test.cpp
void f(int) {}
void g(int) {}

int main()
{
    f(10);
    g(10);
    return 0;
}

$ clang++ -std=c++98 -Wall -Wextra test.cpp
$ clang++ -std=c++03 -Wall -Wextra test.cpp
$ clang++ -std=c++11 -Wall -Wextra test.cpp
$ g++ -std=c++98 -Wall -Wextra test.cpp
$ g++ -std=c++03 -Wall -Wextra test.cpp
$ g++ -std=c++11 -Wall -Wextra test.cpp
$ g++ -v
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
$ clang++ -v
Ubuntu clang version 10.0.1-++20201112101950+ef32c611aa2-1~exp1~20201112092551.202
C だと当然エラーです。
$ cat test3.c
void f(int) {}
void g(int) {}

int main()
{
    f(10);
    g(10);
    return 0;
}

$ gcc -Wall -Wextra test3.c
test3.c: In function ‘f’:
test3.c:1:1: error: parameter name omitted
 void f(int) {}
 ^~~~
test3.c: In function ‘g’:
test3.c:2:1: error: parameter name omitted
 void g(int) {}
 ^~~~
ただし、これを安易に多用すると、引数の意味がわかりにくくなります。Google C++ Style Guide では、自明なもの以外はコメントとして引数名を書くべき(should)としています。

https://google.github.io/styleguide/cppguide.html
Unused parameters that are obvious from context may be omitted:
class Foo {
 public:
  Foo(const Foo&) = delete;
  Foo& operator=(const Foo&) = delete;
};
Unused parameters that might not be obvious should comment out the variable name in the function definition:
class Shape {
 public:
  virtual void Rotate(double radians) = 0;
};

class Circle : public Shape {
 public:
  void Rotate(double radians) override;
};

void Circle::Rotate(double /*radians*/) {}
// Bad - if someone wants to implement later, it's not clear what the
// variable means.
void Circle::Rotate(double) {}


kmckk at 16:36コメント(0) 

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード