web-dev-qa-db-ja.com

#pragmaはかつてC ++ 11標準の一部ですか?

従来、C++に複数のヘッダーが含まれないようにする標準的で移植可能な方法は、 マクロガードスキーム とも呼ばれる#ifndef - #define - #endifpre-compilerディレクティブスキームを使用することでした(以下のコードスニペットを参照)。

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

ただし、ほとんどの実装/コンパイラ(下の図を参照)には、 #pragma once と呼ばれるマクロガードスキームと同じ目的を果たす、より「エレガントな」代替手段があります。 #pragma onceには、マクロガードスキームと比較して、コードの削減、名前の衝突の回避、コンパイル速度の向上など、いくつかの利点があります。

enter image description here

いくつかの調査を行った結果、#pragma onceディレクティブはほとんどすべての既知のコンパイラーでサポートされていますが、#pragma onceディレクティブがC++ 11標準の一部であるかどうかはわかりにくいことがわかりました。

質問:

  • #pragma onceディレクティブがC++ 11標準の一部であるかどうかを誰かが明確にできますか?
  • C++ 11標準の一部ではない場合、今後のリリース(C++ 14以降など)に含める予定はありますか?
  • また、誰かがテクニックのいずれか(マクロガードと#pragma onceなど)を使用することの利点/欠点についてさらに詳しく説明できるといいでしょう。
133
101010

#pragma oncenot標準です。これは広く使用されている(ただし、普遍的ではない)拡張機能であり、使用できます。

  • 移植性の懸念が限られている場合、および
  • すべてのインクルードファイルが常にローカルディスクにあることを確認できます。

標準化が検討されましたが、確実に実装できないため拒否されました。 (問題は、いくつかの異なるリモートマウントを介してファイルにアクセスできる場合に発生します。)

1つの開発内にインクルードガードの競合がないことを確認するのはかなり簡単です。多くの異なる開発で使用される可能性のあるライブラリの場合、明らかな解決策は、インクルードガードを作成するときに、インクルードガード用のランダムな文字を大量に生成することです。 (新しいヘッダーを開くたびに、これを行うための優れたエディターをセットアップできます。)しかし、これがなくても、ライブラリー間の競合に関する問題はまだ発生していません。

103
James Kanze

標準のセクション16.6( N3936 draft)では、#pragmaディレクティブを次のように説明しています。

フォームの前処理指令

# pragma pp-tokensopt new-line

実装が実装定義の方法で動作します。この動作により、翻訳が失敗したり、翻訳者または結果のプログラムが不適合な方法で動作したりする可能性があります。実装によって認識されないプラグマは無視されます。

基本的に#pragma once#pragmaディレクティブの実装固有のインスタンスであり、いいえ、標準ではありません。まだ。

GCC および Clang を含むほとんどの「主要なコンパイラ」で広くサポートされているため、インクルードガードボイラープレートを避けることが推奨される場合があります。

32
Shoe