7

を持つ関数マクロ#define FOO(arg) foo(arg)がありint foo(const char* bar);ます。NDEBUG が定義されている場合、FOO は として定義されますが#define FOO(arg) 0、多くの場合 FOO の戻り値が使用されないため、多くのコンパイラ警告が発生します。このソリューションは ANSI C コンパイラで動作し、警告は発生しません。私はもう試した:

(void)0: 変数に代入できません

static int foo(const char* bar) { return 0; }: 一部のモジュールで未使用の静的関数の警告が発生します

static inline int foo(const char* bar) { return 0; }: C99 コンパイラでのみ動作します

ご協力いただきありがとうございます!

edit1: トレース マクロのようなもので、プロジェクト全体で使用されます。ほとんどの場合、 のようなステートメントとして使用されますFOO("function x called");が、いくつかのケースで を見ましたif (FOO("condition a")) { /* some more debug output */ }。NDEBUG を定義し、最適化を有効にすると、FOO には何も残らないはずです。私はこれを思いつきませんでしたが、この混乱を片付けなければなりません:)。

edit2: gcc リリース ビルドでは、次のフラグが使用されることを追加する必要があります: -O3 -Wall -ansi

edit3: 今のところ、私は__inline int dummy() { return 0; }. __inline は、VisualC と GCC の両方で ansi モードで動作します。

4

3 に答える 3

3

少しコンパイラに依存していると思いますが、これはうまくいくはずです

#ifndef NDEBUG
    #define FOO(arg) foo(arg)
#else
    #define FOO(arg) ((int)0)
#endif

「式には効果がありません」という警告を防ぎ、何もせず、使用時の値はまだ0です。

EDITED
それはそれほど移植性がないようですので、(今)あなたはこれらの条件を持っています:

  • (0)または((int)0)、少なくとも VC 2010 で動作します。
  • __noop2003 年以降のどのバージョンの VC でも動作するはずです。

VC6 は、C4555 警告をまったく発行しないため、問題ではありません。他のコンパイラの場合は、次を使用できます。

  • ((void)0, 0)多くのコンパイラで動作する可能性があります (おそらく、より移植性の高いものでしょうか?)。
  • inline int foo(const char* bar) { return 0; }他のC99コンパイラで動作します(あなたが書いたようstaticに、gccで宣言する必要があるかもしれません)。

他の先史時代の C コンパイラの場合は、@Jobs が指すソリューションを使用します。abs(0)

于 2012-04-17T13:15:47.940 に答える
2

警告を回避するためにできることは次のとおりです

#ifndef NDEBUG
    #define FOO(arg) foo(arg)
#else
    #define FOO(arg) abs(0)
#endif

これが理想的だと言っているわけではありません (stdlib.hたとえば、どこにでも含まれていることを確認する必要があります) が、警告は回避されます。

于 2012-04-17T12:06:39.450 に答える
1

Cバージョンに依存することをします。ヘッダー ファイル内:

#if __STDC_VERSION__ > 199900L
inline int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif

1 つのコンパイル単位で

#if __STDC_VERSION__ < 199900L
int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif

または、ジョブの答えのような古いCバージョンに使用します。これは、最適化されることは確実ですが、警告を生成しない関数です。

于 2012-04-17T12:48:20.257 に答える