2013-07-07 6 views
5

C++(およびC)では、基本的に実装定義の効果を持つ#pragmaという指令があります。しかし、指示が​​何をする可能性があるのか​​何らかの限界がありますか? (私は標準ではない本当のコンパイラは、実際に何をすべきかについて、可能にするかについて尋ねてることに注意してください。)標準では#pragmaに何ができるのですか?

#pragmaが行うことができます私は確信している:

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

    • は、コンパイラが診断を発行することなく、それ以外の場合は、不正なコードを受け入れることを許可する(例えば、コンパイラが構築された新しいをサポートすることを決定するかもしれません:私は推測することは許されますが、確認していないされて

    -inタイプlong long longが、それは診断を発行する必要があります使用して、任意のコード;。この診断は、その後、例えば#pragma long long longを抑制することができ

  • コンパイラは、そうでない場合は法的なコードを拒否することを許可するには、例えばがあるかもしれませんこれにより、コンパイラは、安全でないと考えられる特定のライブラリ関数および/または言語構成の使用をエラーとしてフラグを立てる。

私が実際に疑問許可されていますが、わからないのいずれか:

  • コンパイラは異なるものに法的なコードの意味を変更することを許可する(例えば、コンパイラベンダがそれを考えられていると仮定for条件があっ事後条件(whileを... doのように)、それに応じてforの意味を切り替える#pragma for postcondionを定義した場合、良いアイデア。

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

しかし、標準では実際に何が許可されていますか?許可されているものの、上のリストでカバーされていないものはありますか?

+0

私は長く長いものは許されないと思う: '#pragma'はコンパイラによって無視されるかもしれない。 –

+0

@Alexandre確かに、しかし、私は彼が与えた例のためにそれがどのように問題であるか見ることができません。コンパイラが 'long long long'をサポートしていれば、その使用時に出された警告を抑止する' #pragma'もサポートします。さらに、これはもっと一般的な警告抑制プラグマとどのように違うのですか? –

答えて

5

標準は、その上でかなり明確である:

#pragma pp-tokensopt new-line 

が実装を実装定義方法で動作させる形式の[cpp.pragma]前処理指令。この動作により、翻訳が失敗する可能性があります。またはトランスレータまたは結果のプログラムが非適合の方法で動作する可能性があります。実装で認識されないプラグマは無視されます。

したがって、コンパイラは、#pragmaを見て、何でも望みどおりに行うことができます。

1

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

+0

IMHO gccの古い振る舞いは、 "合法的なコードを拒否する"(* all *コードは拒否され、ゲームを開始することは診断を発行するのに非常に創造的な方法に過ぎません)。 – celtschk

+0

私は何も書かれていないことを書いたことがありませんでした。私は@celtschkに同意します。あなたが何を記述するかは、コンパイラが認識できないプラグマを無視しなければならないためです。 – mah

+0

* all *プラグマのためにコンパイラがそれを行うならば、それは間違いなく "認識"します。 –

3

C++標準のn3337バージョンは

フォーム #pragma pp-tokensopt new-lineの前処理指令は、実装は、実装定義の方法で動作させると言います。 この動作により、変換が失敗するか、変換プログラムまたは が結果として生じるプログラムに不適合な仕方で動作する可能性があります。実装で認識されないプラグマは無視されます。

#pragmaの場合、コンパイラはほとんど何もしたくないと思います。 「翻訳に失敗する」と「翻訳者または結果として生じるプログラムが不適合な仕方で動作する」の両方には、さまざまなオプションが含まれます。

コンパイラに「狂った」ことをさせることが賢明であるということを意味するわけではありません。それは人々を「怒らせる」かもしれませんが、標準の観点からは完全に有効です。

関連する問題