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