リナックスのはじめの方のコードでつまずきました。


以下のような三行のコードがありました。。。順番は不問です。

[code]

    #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))   
    
    struct boot_params boot_params __attribute__((aligned(16)));
    
    BUILD_BUG_ON(sizeof boot_params != 4096);
    
[/code]

上はマクロ、真ん中は構造体？、下は実際の使用だと思います。

マクロの使い方の`*!!`の部分の意味がわかりません。  
真ん中の構造体は`()`が使われている理由がわかりません。そして、`aligned`が何なのか解決できません。  
そのため一番下の結果が予測できません。  
ファイルは、`/linux-4.5.1/arch/x86/boot`内にあるものです。




  1. `#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))`  
conditionが0以外だったらコンパイルエラーにする。  
`!`は単に論理否定で、二つ続けて`!!`とすることで、肯定論理にしています。conditionの値がたとえ10でも論理結果(0 or 1)を返します。  
`char[1 - 2*!!(condition)]`はconditionが0以外だったら
char[-1]になりコンパイルエラーになります。`*`は単なる掛け算です。  
sizeofをとっているのは式にしたいためです。  
式の結果は求めていないのでvoidにキャストしています。

  2. `struct boot_params boot_params __attribute__((aligned(16)));`  
boot_paramsを16byteアライメントに配置する  
`__attribute__((aligned(16)))`はGCCの拡張でC標準ではありませんが、メモリ配置を指定するものです。(
)がやたら多いのは、そういう仕様としか言えません。こちらhttps://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Variable-
Attributes.html を参考にしてください。

  3. `BUILD_BUG_ON(sizeof boot_params != 4096)`  
`sizeof boot_params`が4096でなかったらコンパイルエラーにする。




  1. `#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))`  
conditionが0以外だったらコンパイルエラーにする。  
`!`は単に論理否定で、二つ続けて`!!`とすることで、肯定論理にしています。conditionの値がたとえ10でも論理結果(0 or 1)を返します。  
`char[1 - 2*!!(condition)]`はconditionが0以外だったら
char[-1]になりコンパイルエラーになります。`*`は単なる掛け算です。  
sizeofをとっているのは式にしたいためです。  
式の結果は求めていないのでvoidにキャストしています。

  2. `struct boot_params boot_params __attribute__((aligned(16)));`  
boot_paramsを16byteアライメントに配置する  
`__attribute__((aligned(16)))`はGCCの拡張でC標準ではありませんが、メモリ配置を指定するものです。(
)がやたら多いのは、そういう仕様としか言えません。こちらhttps://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Variable-
Attributes.html を参考にしてください。

  3. `BUILD_BUG_ON(sizeof boot_params != 4096)`  
`sizeof boot_params`が4096でなかったらコンパイルエラーにする。

