名前空間
変種
操作

処理系定義の動作の制御

提供: cppreference.com
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 

処理系定義の動作は #pragma 指令によって制御されます。

目次

[編集] 構文

#pragma pragma_params (1)
_Pragma ( string-literal ) (2) (C++11以上)
1) 処理系定義の方法で動作します。
2) string-literal から 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)

ただし argON または OFF または DEFAULT のいずれかです。

1) ON に設定された場合は、プログラムが浮動小数点環境をアクセスまたは変更することをコンパイラに知らせます。 フラグの確認やモードの変更を補助する最適化 (グローバルな共通部分式の除去やコードの移動、定数の畳み込みなど) が禁止されることを意味します。 デフォルトの値は処理系定義ですが、通常、 OFF です。
2) 浮動小数点式の縮約を許可します。 これはもし式が書かれた通りに正確に評価されたならば観測されたであろう丸め誤差や浮動小数点例外を取り除く最適化です。 例えば、 (x*y) + z を単一の融合積和演算 CPU 命令で実装することを許可します。 デフォルトの値は処理系定義ですが、通常、 ON です。
3) 複素数の乗算、除算、絶対値が、中間オーバーフローの可能性にかかわらず、単純化された数学の公式 (x+iy)×(u+iv) = (xu-yv)+i(yu+xv)(x+iy)/(u+iv) = [(xu+yv)+i(yu-xv)]/(u2
+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
// ヘッダの内容
#endif /* LIBRARY_FILENAME_H */

これにより、任意の翻訳単位においてヘッダの最初以外のすべてのインクルードがコンパイルから除外されます。 すべての現代的なコンパイラは、ヘッダファイルがインクルードガードを使用している事実を記録し、そのガードが未だ定義されている限り、再び遭遇してもそのファイルを再解析しません (例えば gcc を参照してください)。

#pragma once を使用すると、上記のヘッダは以下のように書けます。

#pragma once
// ヘッダの内容

ヘッダガードと異なり、このプラグマは誤って複数のファイルで同じマクロを使用することを不可能とします。 一方、 #pragma once はファイルシステムレベルの同一性に基づいてファイルを除外するため、プロジェクト内の複数の場所に存在する場合、そのヘッダの複数回インクルードに対して保護することはできません。

[編集] #pragma pack

[編集] 関連項目

処理系定義の動作の制御C言語リファレンス

[編集] 外部リンク