インクルードガードとは
ヘッダファイルが複数のソースからインクルードされると、コンパイルエラー(再定義エラー)が発生する。それを防止するもの。
codeA.c
-codeA.h・codeB.hをインクルード
codeA.h
-codeB.hをインクルード
→インクルードガードがない場合、codeB.hが直接・間接的にcodeA.c内で2回インクルードされ、コンパイルエラーとなる。
方法
#ifndef
gerd.cpp
#ifndef MYHEADER_H
#define MYHEADER_H
// ヘッダーの内容
class MyClass {...};
#endif // MYHEADER_H
- C/C++の仕様に完全に準拠しており、すべてのコンパイラで動作する。
- 3行1セットのため、やや冗長。
- ファイル名を変更した場合にマクロ名も手動で修正する必要がある。→インクルードガードのマクロ名は通常、ヘッダーファイル名に基づいて命名されているため。
#pragma once
pragma.cpp
#pragma once
class MyClass {
public:
void sayHello();
};
- 1文で済むため、簡潔。
- ファイル名を変更しても、修正する必要がない。
- コンパイラ固有の指示(pragma)であり、標準C++の機能ではない。→一部古いコンパイラでは使用できないことがある。
結論
使っているコンパイラが古いものでなければ、#pragmaのほうを使ったほうがいいね。
結論の補足(#pragma対応のコンパイラ)
以下のコンパイラは #pragma once
をサポートしている:
コンパイラ名 | 対応状況 | 備考 |
---|---|---|
GCC (GNU Compiler Collection) | ✅ | v3.4以降で正式対応 |
Clang | ✅ | 完全対応 |
Microsoft Visual C++ | ✅ | v4.2以降で対応 |
Intel C++ Compiler | ✅ | 対応しているが、過去に「非推奨」とされたこともあり注意が必要 |
IBM XL C/C++ | ✅ | v13.1.1以降 |
Oracle Developer Studio | ✅ | v12.5以降 |
ARM Keil, IAR, TI Code Composer | ✅ | 組み込み向けでも広く対応 |
TinyCC, SDCC | ✅ | SDCCは未ドキュメントながら対応あり |
※ Comeau C++ や古い組み込み系ツールチェイン(非常に古い/特殊なコンパイラ)では未対応の可能性がある。
結論の補足の補足(使っているコンパイラを確認するには?)
ビルドログや出力メッセージから確認するのが一番早そう
gcc version 11.2.0 (Ubuntu 11.2.0-19ubuntu1)