私のテストによると、次のコードは次のような警告を生成します-Wall -Wextra -O2 -DNDEBUG
。
int a = func(); // warning: unused variable ‘a’
assert(a != 2);
ただし、次のコードはそうではありません。
// no warnings
int a;
a = func();
assert(a != 2);
ただし、にキャストすることで、未使用の変数の警告をいつでも抑制できますvoid
。
int a = func();
(void) a; // suppresses "unused variable" warning
assert(a != 2);
私の知る限り、linea = func()
ステートメントは常に変数の使用としてカウントされますがa
、初期化は使用としてカウントされません。
コンパイラが変更され、診断が改善されたときに、将来起こりうるコンパイラの警告をヘッジしようとはしません。ヘッジによって、誤って有効な警告が抑制されることがあるからです。
アサーションはどのように定義されますか?
標準化委員会とC実装者は、assert
誤った警告を生成しないように注意深く設計されています。一般的なキャストに注意してくださいvoid
...
がないNDEBUG
場合、glibcはassert
大まかに次のように定義します(以外のものを除くabort
)。
#define assert(expr) ((expr) ? (void) 0 : abort())
を使用NDEBUG
すると、glibcはそれを次のように定義します(C標準で義務付けられているように)。
#define assert(expr) ((void) 0)
次のの定義はassert
、式に展開されないため、準拠していません。
#define assert(expr) { if (expr) { ... } } // wrong
C++でも定義が少し異なります。ご覧のとおり、assert
は正しい方法で定義されているため、偽のコンパイラ警告は作成されず、実際には関数呼び出しのように構文的に動作します。