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は機能としてあるので直接的。