6

私は、フラグが設定されているときに多くのエラー報告とログを行う C コードに取り組んでいます。フラグが設定されていない状態でコンパイルすると、未使用の変数の警告DEBUGが生成されることがあります。DEBUG

#ifdef DEBUG
#define CHECK(expr) foo(expr)
#else
#define CHECK(expr)
#endif /* DEBUG */

int x = bar(a, b, c); /* bar has to be called for both DEBUG begin defined and undefined */ 
CHECK(x == SOME_VALUE); /* Produces an "unused variable" warning if DEBUG is undefined

編集: ちょっとしたメモ (それが重要かどうかは不明):CHECKマクロの引数は式であり、単一の variable ではありません

このパターンで、未使用の変数の警告を取り除く最善の方法は何ですか?

私が試したこと/考えたこと:

#ifdef DEBUG
int x = bar(a, b, c);
#else
bar(a, b, c);
#endif
CHECK(x == SOME_VALUE);

bar次に、 (実際の呼び出しではより複雑な)への呼び出しを 2 回記述することを避けるために、次のようにします。

#ifdef DEBUG
int x = 
#endif
bar(a, b, c);
CHECK(x == SOME_VALUE);

ただし、これは正確にクリーンで読みやすいソリューションではないように感じます。より良い方法はありますか?パフォーマンス上の理由から、が定義されCHECK(expr)ていない場合、マクロはコードを生成しないことに注意してください (編集:したがって、評価されるべきではありません)。DEBUGexpr

上で概説した方法よりもエレガントな方法はありますか?

4

3 に答える 3

8
#ifdef DEBUG
    #define CHECK(x) x
#else
    #define CHECK(x) ((void)sizeof((void)(x),0))
#endif

これにより、考えられるすべての問題に対処できると思います。

  • sizeof式がまったく評価されないことを保証するため、その副作用は発生しません。これは、 などのデバッグ専用構成の通常の動作と一致するようにするためassertです。
  • ((x), 0)コンマ演算子を使用して、 の実際の型を飲み込みます(x)これは、VLA が評価をトリガーするのを防ぐためです
  • (void)(x)andの結果を明示的に無視するsizeofため、「未使用の値」の警告は表示されません。
于 2016-05-24T11:41:51.320 に答える
4

私があなたの質問を正しく理解していれば、次のようなことができます

#ifdef DEBUG
.
.
#else
#define CHECK(expr) ((void)(expr))
#endif /* DEBUG */

警告を取り除くために。

于 2016-05-24T11:10:00.753 に答える
0

このソリューションでは、中間変数は必要ありません。

#define DEBUG

#define DOCHECK(a) printf("DOCHECK %d\n", a)

#ifndef DEBUG
#define CHECK(a, b) a
#else
#define CHECK(a, b) do {int x = a; DOCHECK(x == b);} while (0)
#endif

int bar(int x, int y)
{
  return x+y;
}    

int main()
{
  CHECK(bar(2,3), 2+3);
  return 0;
}
于 2016-05-24T11:38:32.713 に答える