従来、C++に複数のヘッダーが含まれないようにする標準的で移植可能な方法は、 マクロガードスキーム とも呼ばれる#ifndef - #define - #endif
pre-compilerディレクティブスキームを使用することでした(以下のコードスニペットを参照)。
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
ただし、ほとんどの実装/コンパイラ(下の図を参照)には、 #pragma once
と呼ばれるマクロガードスキームと同じ目的を果たす、より「エレガントな」代替手段があります。 #pragma once
には、マクロガードスキームと比較して、コードの削減、名前の衝突の回避、コンパイル速度の向上など、いくつかの利点があります。
いくつかの調査を行った結果、#pragma once
ディレクティブはほとんどすべての既知のコンパイラーでサポートされていますが、#pragma once
ディレクティブがC++ 11標準の一部であるかどうかはわかりにくいことがわかりました。
#pragma once
ディレクティブがC++ 11標準の一部であるかどうかを誰かが明確にできますか?#pragma once
など)を使用することの利点/欠点についてさらに詳しく説明できるといいでしょう。#pragma once
はnot標準です。これは広く使用されている(ただし、普遍的ではない)拡張機能であり、使用できます。
標準化が検討されましたが、確実に実装できないため拒否されました。 (問題は、いくつかの異なるリモートマウントを介してファイルにアクセスできる場合に発生します。)
1つの開発内にインクルードガードの競合がないことを確認するのはかなり簡単です。多くの異なる開発で使用される可能性のあるライブラリの場合、明らかな解決策は、インクルードガードを作成するときに、インクルードガード用のランダムな文字を大量に生成することです。 (新しいヘッダーを開くたびに、これを行うための優れたエディターをセットアップできます。)しかし、これがなくても、ライブラリー間の競合に関する問題はまだ発生していません。
標準のセクション16.6( N3936 draft)では、#pragma
ディレクティブを次のように説明しています。
フォームの前処理指令
# pragma pp-tokensopt new-line
実装が実装定義の方法で動作します。この動作により、翻訳が失敗したり、翻訳者または結果のプログラムが不適合な方法で動作したりする可能性があります。実装によって認識されないプラグマは無視されます。
基本的に#pragma once
は#pragma
ディレクティブの実装固有のインスタンスであり、いいえ、標準ではありません。まだ。
GCC および Clang を含むほとんどの「主要なコンパイラ」で広くサポートされているため、インクルードガードボイラープレートを避けることが推奨される場合があります。