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