2

たとえば、warning: unnamed struct/union that defines no instancesコンパイラのコマンド ライン オプションではなく、ソース ファイル内の " " を削除するにはどうすればよいでしょうか。

CONST_BUG_ONコンパイル時に一部の const 値をチェックするために使用するC マクロを定義したいと考えて います。

#define CONST_BUG_ON(e)        struct  {int a:!(e);}

警告warning: unnamed struct/union that defines no instancesが表示されますが、この場合は実際の問題ではありません。

ありがとうトム・タナー

#define CONST_BUG_ON_3(e, l) struct buggy##l {int a:!(e);}
#define CONST_BUG_ON_2(e, l) CONST_BUG_ON_3(e, l)
#define CONST_BUG_ON(e) CONST_BUG_ON_2(e, __LINE__)

それは良いことですが、まだいくつか問題があります: fileaの 6 行目に CONST_BUG_ON(e) が含まれていて、 fileaが file に含まれていて、 filebの 6 行b目に CONST_BUG_ON(e) が含まれている場合、gcc は再定義エラーを訴えます。__COUNTER__instade of の使用__LINE__は完璧かもしれませんが、私の古いコンパイラは をサポートしていません__COUNTER__

ありがとうバジル・スタリンケビッチ

#define CONST_BUG_ON(e) do { \
   int tab[__builtin_constant_p(e)?1:-1] = {0}; \
   if (tab[0]) abort(); } while (0)

これは C ステートメントであり、関数内にのみ配置できます。関数の外で使用したいのです。

4

4 に答える 4

3

コンパイラの不満を解決する 1 つの方法は、インスタンスを定義しない名前のない構造体があることです。これは、それに名前を付けることです。

#define CONST_BUG_ON(e)        struct ForDebuggingOnly {int a:!(e);}

e必要な式のテストを取得する別の方法は、 true の場合に不正なサイズの配列を宣言する (定義しない) ことです。

#define CONST_BUG_ON(e)    extern int ForDebuggingOnly[(e) ? -1 : 1]
于 2012-08-27T13:11:30.523 に答える
1

あなたがしようとしているのは、コンパイル時アサーションまたはコンパイル時アサートマクロと呼ばれているようです。これにはさまざまな方法がありますが、通常は、アサーションが失敗したときに負の次元の配列を使用します。多くのプロジェクトがこのマクロCT_ASSERT()を呼び出しており、それらに関連する Stackoverflow の質問がたくさんあります

于 2012-08-27T13:25:48.107 に答える
1

最近の GCC コンパイラを想定すると、おそらく__builtin_constant_pを使用してコンパイル時の定数をテストできます。

  #define CONST_BUG_ON(e) do { \
       int tab[__builtin_constant_p(e)?1:-1] = {0}; \
       if (tab[0]) abort(); } while (0)

いくつかの警告を無視することについての質問については、おそらくGCC 診断プラグマが役立つ可能性があります。

宣言コンテキストでのみ機能させたい場合CONST_BUG_ONは、試してみてください

  #define CONST_BUG_ON(e) CONST_BUG_AT(e,__LINE__)
  #define CONST_BUG_AT(e,l) \
     extern int tab_##l[__builtin_constant_p(e)?0:-1];

最後に、おそらくMELT (GCC を拡張する高レベルのドメイン固有言語) を使用して GCC コンパイラを (特定のプラグマで) カスタマイズすることもできますが、それには何日もの作業が必要です。

于 2012-08-27T12:47:06.710 に答える
1

マクロマジックを使用して、行番号を渡すことで一意の ID を自分自身に与えることができます

#define CONST_BUG_ON_3(e, l) struct buggy##l {int a:!(e);}
#define CONST_BUG_ON_2(e, l) CONST_BUG_ON_3(e, l)
#define CONST_BUG_ON(e) CONST_BUG_ON_2(e, __LINE__)

それはかなり厄介ですが、使用されるたびに一意の名前が付けられます (第 2 レベルの間接化は偽物かもしれませんが、これは、時の試練に耐えたコードで私が持っているものです)。

于 2012-08-27T13:17:51.007 に答える