処理系定義の動作制御
処理系定義の動作は、#pragma ディレクティブによって制御されます。
目次 |
[編集] 構文
#pragma pragma-params |
(1) | ||||||||
_Pragma( string-literal ) |
(2) | (C++11以降) | |||||||
L プレフィックス (もしあれば)、外側の引用符、先頭/末尾の空白を除去し、各 \" を " に、各 \\ を \ に置き換え、結果をトークン化し (変換フェーズ 3 と同様)、その結果を (1) の #pragma への入力として使用します。[編集] 解説
プラグマディレクティブは、コンパイラ警告の無効化やアラインメント要件の変更など、コンパイラの処理系固有の動作を制御します。認識されないプラグマはすべて無視されます。
[編集] 非標準プラグマ
ISO C++ 言語標準は、コンパイラがいかなるプラグマもサポートすることを義務付けていません。しかし、いくつかの非標準プラグマが複数の実装でサポートされています。
[編集] #pragma STDC
ISO C 言語標準は、C コンパイラが以下の 3 つのプラグマをサポートすることを義務付けており、一部の C++ コンパイラベンダーは、C++ フロントエンドでそれらをさまざまな程度でサポートしています。
#pragma STDC FENV_ACCESS arg |
(1) | ||||||||
#pragma STDC FP_CONTRACT arg |
(2) | ||||||||
#pragma STDC CX_LIMITED_RANGE arg |
(3) | ||||||||
ここで arg は ON, OFF, または DEFAULT のいずれかです。
ON に設定すると、プログラムが浮動小数点環境にアクセスまたは変更することをコンパイラに通知します。これは、フラグテストやモード変更を妨害する可能性のある最適化 (例: グローバル共通部分式除去、コード移動、定数畳み込み) が禁止されることを意味します。デフォルト値は処理系定義で、通常は OFF です。ON です。+v2
)、および |x+iy| = √x2
+y2
を使用できることを通知します。言い換えれば、プログラマはそれらの関数に渡される値の範囲が制限されていることを保証します。デフォルト値は
OFF です。上記の 3 つのプラグマのいずれかが、すべての外部宣言の外側、または複合ステートメント内のすべての明示的な宣言とステートメントの前に現れる以外のコンテキストで出現した場合、プログラムの動作は未定義です。
注: これらのプラグマをサポートしないコンパイラは、gcc の -fcx-limited-range や -ffp-contract のような同等のコンパイル時オプションを提供する場合があります。
[編集] #pragma once
#pragma once は、ほとんどの最新のコンパイラでサポートされている非標準プラグマです。ヘッダファイルに出現する場合、同じソースファイルに複数回 (直接的または間接的に) インクルードされた場合でも、一度だけ解析されることを示します。
同じヘッダが複数回インクルードされるのを防ぐ標準的なアプローチは、インクルードガードを使用することです。
#ifndef LIBRARY_FILENAME_H #define LIBRARY_FILENAME_H // contents of the header #endif /* LIBRARY_FILENAME_H */
これにより、任意の翻訳単位でのヘッダの最初のインクルードを除くすべてがコンパイルから除外されます。すべての最新のコンパイラは、ヘッダファイルがインクルードガードを使用しているという事実を記録し、ガードがまだ定義されている限り、再度検出されてもファイルを再解析しません (例: gcc を参照)。
#pragma once を使用すると、同じヘッダは次のように現れます。
#pragma once // contents of the header
ヘッダガードとは異なり、このプラグマは同じマクロ名を複数のファイルで誤って使用することを不可能にします。一方で、#pragma once を使用する場合、ファイルはファイルシステムレベルの同一性に基づいて除外されるため、プロジェクト内の複数の場所に存在するヘッダを二重にインクルードすることから保護することはできません。
[編集] #pragma pack
このプラグマ群は、後続で定義されるクラスおよび共用体メンバの最大アラインメントを制御します。
#pragma pack(arg)
|
(1) | ||||||||
#pragma pack()
|
(2) | ||||||||
#pragma pack(push)
|
(3) | ||||||||
#pragma pack(push, arg)
|
(4) | ||||||||
#pragma pack(pop)
|
(5) | ||||||||
ここで arg は 2 の小さいべき乗であり、バイト単位の新しいアラインメントを指定します。
#pragma pack はクラスのアラインメントを減少させる可能性がありますが、クラスをオーバーアラインにすることはできません。
GCC および MSVC の具体的な詳細も参照してください。
| このセクションは未完成です 理由: データメンバに対するこれらのプラグマの効果、およびそれらを使用することの長所と短所を説明する。参照元 |
| このセクションは未完成です 理由: 例がありません |
[編集] 参照
- C++23標準 (ISO/IEC 14882:2024)
- 15.9 Pragma directive [cpp.pragma]
- C++20 standard (ISO/IEC 14882:2020)
- 15.9 Pragma directive [cpp.pragma]
- C++17 standard (ISO/IEC 14882:2017)
- 19.6 Pragma directive [cpp.pragma]
- C++14 standard (ISO/IEC 14882:2014)
- 16.6 Pragma directive [cpp.pragma]
- C++11 standard (ISO/IEC 14882:2011)
- 16.6 Pragma directive [cpp.pragma]
- C++98 標準 (ISO/IEC 14882:1998)
- 16.6 Pragma directive [cpp.pragma]
[編集] 関連項目
| C ドキュメント (Implementation defined behavior control について)
|
[編集] 外部リンク
| 1. | Visual Studio の C++ プラグマ |
| 2. | GCC で受け入れられるプラグマ |
| 3. | IBM AIX XL C 16.1 の個々のプラグマの説明と標準プラグマ |
| 4. | Sun Studio 11 C++ User's Guide の付録 B. プラグマ |
| 5. | Intel C++ コンパイラのプラグマ |
| 6. | HP aCC A.06.25 のリリースノート (プラグマを含む) |