C言語の「:-!!」とは何ですか? 質問する

C言語の「:-!!」とは何ですか? 質問する

この奇妙なマクロコードに出会ったのは/usr/include/linux/kernel.h:

/* Force a compilation error if condition is true, but also produce a
   result (of value 0 and type size_t), so the expression can be used
   e.g. in a structure initializer (or where-ever else comma expressions
   aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))

:-!!をするのですか?


更新:最近、マクロは/usr/include/linux/build_bug.h

ベストアンサー1

これは実際には、式 e が 0 に評価できるかどうかを確認し、評価できない場合はビルドを失敗させる方法です。

BUILD_BUG_OR_ZEROこのマクロの名前は少々間違っています。ではなく のような名前にすべきです...ON_ZERO。(これは紛らわしい名前であるかどうかについての議論が時々ある

この表現は次のように読みます。

sizeof(struct { int: -!!(e); }))
  1. (e): 式を計算しますe

  2. !!(e): 論理的に 2 回否定します: 0if e == 0; else 1

  3. -!!(e): ステップ 2 の式を数値的に否定します。0の場合0、 、それ以外の場合は-1

  4. struct{int: -!!(0);} --> struct{int: 0;}: ゼロの場合は、幅がゼロの匿名整数ビットフィールドを持つ構造体を宣言します。すべて問題なく、通常どおり続行されます。

  5. struct{int: -!!(1);} --> struct{int: -1;}: 一方、ゼロでない場合は、負の数になります。負の幅を持つビットフィールドを宣言すると、コンパイル エラーになります。

したがって、構造体の幅が 0 のビットフィールド (これは問題ありません) または負の幅のビットフィールド (これはコンパイル エラーです) のいずれかになります。次に、sizeofそのフィールドを取得して、適切な幅の を取得しますsize_t( がゼロの場合は 0 になりますe)。


何人かの人はこう尋ねました:なぜ を使わないのですかassert?

keithmo の回答ここに良い回答があります:

これらのマクロはコンパイル時のテストを実装しますが、assert() は実行時のテストです。

まさにその通りです。実行時にカーネルの問題を検出したくはありません。カーネルはオペレーティング システムの重要な部分です。コンパイル時に問題を検出できれば、その分だけ良いのです。

おすすめ記事