35

ここに画像の説明を入力

http://en.wikipedia.org/wiki/Pragma_once
これらすべてのコンパイラがサポートしている場合でも、インクルード ガードを使用する必要があり#pragma onceますか?
スタック オーバーフローに関する多くの回答では、互換性のために両方を使用するように言われていますが、それがまだ正しいかどうかはわかりません。現在サポートされていないコンパイラは#pragma onceどれですか?

両方を使用することが、widley が採用される前の単なる推奨事項だったのか、それとも両方の方法を使用する十分な理由があるのか​​はわかりません。
使用#pragma onceするだけで問題が発生する例はありますか?

4

3 に答える 3

14

それは、プログラムの移植性がどの程度期待されるかによって異なります。

確実にサポートされていることがわかっているコンパイラで動作するはずのプログラムを書いている限り、 を#prama once使用#pragma onceするだけで十分です。ただし、そうすると、実装定義の機能をサポートする一連のコンパイラにプログラムを制限します。

プログラムをすべてのコンパイラ#pragma onceで動作させる必要がある場合は、両方のガードを使用して含める必要があります。

コンパイラがサポートしていない場合は[Ref#1]#pragma onceを単に無視します。そのような場合、ヘッダー ガードが目的を果たします。そのため、ターゲット コンパイラでサポートされている機能を認識していない場合に両方を使用しても問題はありません。 .

したがって、プログラムをさまざまなコンパイラで 100% 移植可能にしたい場合、理想的な方法は、インクルード ガードのみを使用することです。の動作は実装定義であるため、@CharlesBailey が正しく指摘している#pragma onceように、不明なコンパイラでの動作はプログラムに悪影響を与える可能性があります。


[Ref#1]
標準 C++03: 16.6 プラグマ ディレクティブ

フォームの前処理ディレクティブ

# pragma pp-tokensopt new-line

実装が実装定義の方法で動作するようにします。実装によって認識されないプラグマは無視されます。

于 2012-11-12T07:04:23.490 に答える
10

これは非標準なので、安全に使用したい場合はインクルードガードを使用してください

于 2012-11-12T07:04:12.797 に答える
7

あなたの表が示すように、現在主流で使用されているコンパイラでサポートされていないものに遭遇することは非常にまれ#pragma onceです。コード ベースをクリーンで安価に維持するには、リファクタリングの絶え間ない努力が必要です。クラスの名前を変更したり、一部のコードを移動したりするたびにインクルード ガードを更新する必要があると、この作業に大きな負担がかかります。

したがって、いくつかのニッチなコーナーケースや壊れたビルドシステムを除けば#pragma once、実際には安全に信頼できると言えます。生産性とコードの品質に関心がある場合は、 only を使用#pragma onceするのが当然の選択と思われます。

例外は、太陽の下ですべてのコンパイラをサポートする必要があるライブラリを作成している場合、またはこの機能を持たないこれらのまれなコンパイラのいずれかを使用する必要があるほど残念なことです。

于 2014-08-08T09:52:32.980 に答える