にたまごほうれん草アーカイブ

はてなダイアリーで書いてた「にたまごほうれん草」という日記のアーカイブです。現在は「にたまごほうれん草ブログ」を運営中です。

do { 〜 } while (0) なマクロ

複数の式からなる関数マクロに、こんな表現があった。

#define nullcheck(x) do {         \
        if (x == NULL) {           \
            printf("NULL!\n");     \
        } else {                   \
            printf("not NULL!\n"); \
        }                          \
    } while(0)

なぜdo〜while(0)で囲ってあるのかと思ったが、こうすることによって文末のセミコロンが抜けた場合にコンパイルが通ってしまうことを避けられるから、のらしい。

/* コンパイル通る */
#define nullcheck1(x) if (x == NULL) {          \
        printf("NULL!\n");                      \
    } else {                                    \
        printf("not NULL!\n");                  \
    }                                           

int main(int argc, char* argv[]) 
{
    int *x = NULL;
    nullcheck1(x)   /* セミコロン抜け */
    return 0;
}
/* これだとコンパイル通らない */
#define nullcheck2(x) do {         \
        if (x == NULL) {           \
            printf("NULL!\n");     \
        } else {                   \
            printf("not NULL!\n"); \
        }                          \
    } while(0)

int main(int argc, char* argv[]) 
{
    int *x = NULL;
    nullcheck2(x)   /* セミコロン抜け */
    return 0;
}

どっちかっていうとバッドノウハウに近い感じかなぁ。