11

現在、未使用の変数の警告を抑制するために、次の関数テンプレートを使用しています。

template<typename T>
void
unused(T const &) {
  /* Do nothing. */
}

ただし、Linuxからcygwinに移植すると、g ++ 3.4.4でコンパイラエラーが発生します(Linuxでは3.4.6なので、これはバグ修正ですか?):

Write.cpp: In member function `void* Write::initReadWrite()':
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1

usedの引数は、次のように宣言されたメンバー変数です。

  volatile bool readWriteActivated;

これはコンパイラのバグですか、それとも私のコードのバグですか?

最小限のテストケースは次のとおりです。

template<typename T>
void unused(T const &) { }

int main() {
  volatile bool x = false;
  unused(!x); // type of "!x" is bool
}
4

5 に答える 5

28

パラメータを実際に使用していないことを示す実際の方法は、名前を付けないことです。

int f(int a, float) {
     return a*2;
}

未使用のフロートについて警告することなく、すべての警告をオンにしてどこでもコンパイルされます。プロトタイプに引数に名前が含まれていても(たとえばint f(int a, float f);)、文句を言うことはありません。

于 2009-12-15T09:25:06.740 に答える
9

これが移植可能であるかどうかは100%わかりませんが、これは、未使用の変数に関する警告を抑制するために通常使用しているイディオムです。ここでのコンテキストは、キャッチSIGINTとを取得するためにのみ使用されるシグナルハンドラーであるSIGTERMため、関数が呼び出された場合は、プログラムを終了する時間であることがわかります。

volatile bool app_killed = false;
int signal_handler(int signum)
{
    (void)signum; // this suppresses the warnings
    app_killed = true;
}

__attribute__((unused))Visual C ++のマクロに頼らずにキャストからボイドへのトリックが機能するため、パラメーターリストをで乱雑にするのは嫌いです。

于 2009-12-15T05:35:02.850 に答える
4

これはコンパイラのバグであり、既知の回避策はありません。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42655

v4.4で修正されています。

于 2009-12-16T01:51:59.510 に答える
2

GCCでは、次のようにマクロを定義できます。

#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif 

このマクロでマークされたパラメーターは、GCCが発する未使用の警告を抑制します(そして、パラメーターの名前を接頭辞UNUSED_)に変更します。Visual Studioの場合、#pragmaディレクティブを使用して警告を抑制できます。

于 2009-12-15T04:56:35.540 に答える
2

haaveeによって提案された答え(urによって修正された)は、私が通常使用するものです:

int f(int a, float /*epsilon*/) {
     return a*2;
}

実際の問題は、引数がメソッドで常に使用されるとは限らない場合に発生します。例

int f(int a, float epsilon) {
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

ここで、パラメーター名epsilonをコメントアウトすることはできません。これは、ロギングビルドが破損するためです(コードが非常に読みにくくなるため、引数リストに別の#ifdefを挿入したくありません)。

したがって、最善の解決策はトムの提案を使用することだと思います。

int f(int a, float epsilon) {
(void) epsilon;    // suppress compiler warning for possibly unused arg
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

私の唯一の心配は、一部のコンパイラが「(void)イプシロン」について警告する可能性があることです。ステートメント、たとえば「ステートメントは効果がありません」という警告など-使用する可能性のあるすべてのコンパイラでテストする必要があると思います...

于 2010-10-06T16:58:39.647 に答える