C言語の二重インクルード(多重インクルード)防止について

    C言語のヘッダファイルでおまじないのように書いているコレ。

    #ifndef  _FOO_H_
    #define  _FOO_H_
    
    #endif
    

    インクルードガードという。いったいなんなのか調べた。

    無限ループ防止

    互いのヘッダファイルをインクルードしあうと、コンパイル時に無限ループに陥る。

    foo.h

    #include "bar.h"
    

    bar.h

    #include "foo.h"
    

    実行結果

      $gcc foo.c bar.c
         ... 
    		 from foo.h:1,
    		 from bar.h:4,
    		 from foo.h:1,
    		 from bar.h:4,
    		 from foo.h:1,
    		 from bar.h:4,
    		 from foo.h:1,
    		 from bar.h:4,
    		 from foo.h:1,
    		 from bar.h:4,
    		 from foo.h:1,
    		 from foo.c:2:
    foo.h:1:17: error: #include nested too deeply
     #include "bar.h"
    

    構造体のコンパイルエラー

    一つの.hにある構造体を二つの.cでインクルードすると、コンパイルエラーが発生する仕様。

    foo.h

    struct test{
      int test;
    };
    

    bar.c / foo.c

    #include "foo.h"
    

    実行結果

    
    % gcc bar.c foo.c
    In file included from bar.c:3:0:
    foo.h:2:8: error: redefinition of ‘struct test’
     struct test{
            ^
    In file included from bar.h:4:0,
                     from bar.c:2:
    foo.h:2:8: note: originally defined here
     struct test{
    

    progma onceについて

    インクルードガードを実現するためのコンパイラの仕組みに、#pragma onceというのがある。

    ヘッダファイルの先頭に以下を記述するだけ。

    #pragma once
    

    #ifndefは別の機能をたまたま応用にしているに過ぎないが、 #pragma onceは機能としてあるので直接的。