__attribute__の括弧

Binary 2.0カンファレンス2006 に動画とIRCで参加してきました。
http://0xcc.net/blog/archives/000149.html
動画をキャプチャしながら見ていたので、IRCとのタイムラグが結構ありました。
技術的にはブログなどで既知のものが多かったんですが、PS3 LinuxでのプレゼンにWiiリモコン使うなど、ネタとしては面白かったです。


最初の質問で「gccの__attribute__はなぜ括弧が二重になっているのか?」というのがあって、そのときには思いつかなかったのですが、休憩中にひらめいてIRCにちょっと書き込みました。

19:32 >hamigaki< 多分、gcc以外でマクロで代用するためですよ>括弧
19:32 >hamigaki< 二重でないと、コンマがかけない

これだけだと、分からない人もいたと思うのでちょっと解説しておきます。


そもそも__attribute__というのがどういうものかと言うと、

// 決して読み出し元に戻らない関数
void exit() __attribute__((noreturn));

のように関数(や型や変数)に特殊な属性を付加するgcc独自の仕組みです。
(gcc以外の一部のコンパイラでも使用可能)
詳しくはgccのマニュアルを参照してください。
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Function-Attributes.html


このままではgccでしかコンパイルできなくなるので、

// gcc以外では空マクロにする
#if !defined(__GNUC__)
    #define __attribute__(a)
#endif

のようにすることが想定されています。


また、複数の属性を設定したい場合は、

void exit() __attribute__((noreturn)) __attribute__((cdecl));

または、

void exit() __attribute__((noreturn, cdecl));

と書けます。
下の記法をgcc以外で括弧を二重にしないで書いてしまうと、

void exit() __attribute__(noreturn, cdecl); // 間違い

__attribute__()が2引数のマクロと解釈されコンパイルできません。
これを1引数と見なすためには、「noreturn, cdecl」を括弧で括る必要あります。
つまり、gccのパーサーは括弧が一重でも困らないのですが、他のコンパイラに配慮して二重括弧を要求するわけです。
たぶん。


#早速シンタックス・ハイライトを使ってみました。