[解決済み] 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); }))
とは何ですか?
:-!!
を行うか?
どのように解決するのですか?
これは、実質的には 式eが0と評価できるかどうかをチェックし、評価できない場合はビルドを失敗させる方法です。 .
このマクロはやや名前が間違っています。
BUILD_BUG_OR_ZERO
よりも、むしろ
...ON_ZERO
. (これまでにも
という名称は紛らわしいのではないか、という議論が時折なされています。
.)
このように式を読む必要があります。
sizeof(struct { int: -!!(e); }))
-
(e)
: 計算式e
. -
!!(e)
: 論理的に2回否定する。0
もしe == 0
そうでない場合は1
. -
-!!(e)
: 手順 2 の式を数値で否定する。0
であった場合0
そうでない場合は-1
. -
struct{int: -!!(0);} --> struct{int: 0;}
: 0であった場合、幅が0の匿名整数ビットフィールドを持つ構造体を宣言します。すべてうまくいき、通常通りに進みます。 -
struct{int: -!!(1);} --> struct{int: -1;}
: 一方、もしそれが ではない ゼロであれば、何らかの負数になります。任意のビットフィールドを ネガティブ の幅はコンパイルエラーになります。
つまり、構造体の幅が 0 のビットフィールドは問題ありませんが、負の幅のビットフィールドはコンパイル エラーになります。そこで
sizeof
そのフィールドを取得するため
size_t
を適切な幅で指定します (この幅は
e
がゼロの場合)。
という質問もありました。
を使うだけではダメなのでしょうか?
assert
?
keithmoの回答 が良い回答をしています。
これらのマクロはコンパイル時のテストを実装しており、assert()は実行時のテストです。
まさにその通りです。の問題を検出したいとは思わないでしょう。 カーネル もっと早く発見できたはずのものを、実行時に発見してしまうのです。これはオペレーティングシステムの重要な部分です。コンパイル時に問題を検出できるのであれば、それに越したことはありません。
関連
-
[解決済み] C言語の書式指定子 %ul と %lu の違いは何ですか?
-
[解決済み] C 言語で const char* を char* に変換するには?
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] Linux上で動作するC++コードのプロファイリングを行うにはどうすればよいですか?
-
[解決済み] C++でextern "C "を使用した場合の効果は?
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み] POSIX」の意味を教えてください。
-
[解決済み] C言語でのブーリアン値の使用
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
構造体の配列--[エラー] '['トークンの前に一次式があることが予想される
-
Cエラー [エラー] 代入_Ashesの左オペランドにlvalueが必要です-プログラマーズ・シークレット
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
[解決済み] C - Setデータ構造を実装するには?
-
[解決済み] mallocの結果はキャストするのですか?
-
[解決済み] C言語で配列のサイズを決定するにはどうすればよいですか?
-
[解決済み] Cプリプロセッサはなぜ "linux "という単語を定数 "1 "と解釈するのですか?
-
[解決済み] C言語標準に準拠した構造体の初期化方法
-
[解決済み] C言語でオブジェクト指向のコードを書くとしたら、どのようにすればよいのでしょうか?[クローズド]
-
[解決済み] C++における二重否定