5

C++ (および C) には、#pragma基本的に実装定義の効果を持つディレクティブがあります。ただし、ディレクティブの機能に制限はありますか? (実際のコンパイラが実際に何をするかではなく、標準で許可されていることについて質問していることに注意してください。)

私が確信している#pragmaことは次のとおりです。

  • すべてが有効な C++ になるいくつかのコンパイル オプションの 1 つを選択できるようにします。たとえば、いくつかの使用可能な ABI の 1 つを選択するか、特定の実装定義オプションを切り替えます。

私が推測することは許可されていますが、よくわかりません:

  • コンパイラが診断を発行せずに不正なコードを受け入れられるようにします (たとえば、コンパイラは新しい組み込みの type をサポートすることを決定するlong long long場合がありますが、それを使用するコードは診断を発行する必要があります。この診断は、たとえば#pragma long long long.

  • コンパイラが正当なコードを拒否できるようにします。たとえば#pragma strict、コンパイラが、安全でないと見なされる特定のライブラリ関数や言語構造の使用をエラーとしてフラグ付けする可能性があります。

私が実際に疑問に思っていることは許可されていますが、どちらもわかりません:

  • コンパイラが正当なコードのセマンティクスを別のものに変更できるようにします (たとえば、コンパイラ ベンダーforが、条件が事後条件 ( do…のように) である場合にそれを良い考えと見なし、それに応じて の意味を切り替えるようにwhile定義したとします) 。#pragma for postcondionfor

私が後者を疑う理由は、コンパイラが認識しないプラグマを無視することが許可されているため、プラグマによるセマンティクスの変更により、同じプログラムが異なるコンパイラで異なるセマンティクスを持つようになるためです。

しかし、標準では実際に何が許可されているのでしょうか? また、許可されているものの、上記のリストに含まれていないものはありますか?

4

3 に答える 3

5

標準はそれについて非常に明確です:

[cpp.pragma]フォームの前処理ディレクティブ

#pragma pp-tokensopt new-line

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

したがって、コンパイラは、#pragma.

于 2013-07-07T10:36:28.370 に答える
1

文書化されている限り、コンパイラは絶対にすべてを行うことができます。非常に古いバージョンの gcc は、プラグマを見つけると、コンパイルを停止し、当時存在していたテキストモード ゲームの 1 つを見つけて起動しようとしました。ユーザーガイドにセクションがあったため、これは完全に標準に準拠していました。

于 2013-07-07T10:35:20.610 に答える