Namespaces
Variants

Implementation defined behavior control

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

実装定義動作は #pragma ディレクティブによって制御されます。

目次

構文

#pragma pragma-params (1)
_Pragma( string-literal ) (2) (C++11以降)
1) 実装定義の動作を示します。
2) string-literal から L プレフィックス(存在する場合)、外側の引用符、および先頭/末尾の空白を除去し、各 \ " " に、各 \\ \ に置換した後、結果をトークン化し( 翻訳フェーズ3 と同様)、その結果を (1) #pragma への入力として使用する。

説明

Pragmaディレクティブは、コンパイラ警告の無効化やアライメント要件の変更など、コンパイラの実装固有の動作を制御します。認識されないプラグマは無視されます。

非標準プラグマ

ISO C++言語標準では、コンパイラがプラグマをサポートすることを要求していません。しかし、いくつかの非標準プラグマが複数の実装でサポートされています:

#pragma STDC

ISO C言語標準では、Cコンパイラが以下の3つのプラグマをサポートすることを要求しており、一部のC++コンパイラベンダーは、自社のC++フロントエンドにおいて様々な程度でこれらをサポートしています:

#pragma STDC FENV_ACCESS 引数 (1)
#pragma STDC FP_CONTRACT 引数 (2)
#pragma STDC CX_LIMITED_RANGE 引数 (3)

where arg is either ON , OFF , or DEFAULT .

1) ON に設定された場合、プログラムが floating-point environment にアクセスまたは変更することをコンパイラに通知します。これは、フラグテストやモード変更を妨害する可能性のある最適化(例えば、大域共通部分式削除、コード移動、定数畳み込み)が禁止されることを意味します。デフォルト値は実装定義であり、通常は 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)]/(u 2
+v 2
)
および |x+iy| = x 2
+y 2
を使用することをコンパイラに通知します。言い換えれば、プログラマはこれらの関数に渡される値の範囲が限定されていることを保証します。デフォルト値は OFF です。

プログラムの動作は、上記の3つのプラグマのいずれかが、すべての外部宣言の外部、または複合文内のすべての明示的な宣言と文に先行する以外の文脈で現れた場合、未定義です。

注記: これらのプラグマをサポートしていないコンパイラは、gccの -fcx-limited-range および -ffp-contract のような同等のコンパイル時オプションを提供する場合があります。

#pragma once

#pragma once は非標準のプラグマであり、 大多数のモダンなコンパイラ でサポートされています。ヘッダーファイル内に記述された場合、同じソースファイル内で(直接または間接的に)複数回インクルードされても、そのファイルが一度だけパースされることを示します。

同じヘッダーの複数回インクルードを防止する標準的なアプローチは、 include guards を使用することです:

#ifndef LIBRARY_FILENAME_H
#define LIBRARY_FILENAME_H
// ヘッダーの内容
#endif /* LIBRARY_FILENAME_H */

翻訳単位内でのヘッダーファイルの最初のインクルード以降のすべてのインクルードをコンパイルから除外するため。すべてのモダンなコンパイラは、ヘッダーファイルがインクルードガードを使用している事実を記録し、ガードがまだ定義されている限り、ファイルが再度検出されても再解析を行いません(例: gcc を参照)。

#pragma once を使用すると、同じヘッダーが次のように表示されます

#pragma once
// ヘッダーの内容

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

#pragma pack

このプラグマファミリーは、後に定義されるクラスおよび共用体のメンバーの最大アラインメントを制御します。

#pragma pack( arg ) (1)
#pragma pack() (2)
#pragma pack(push) (3)
#pragma pack(push, arg ) (4)
#pragma pack(pop) (5)

where arg は2の小さなべき乗であり、新しいアラインメントをバイト単位で指定します。

1) 現在のアライメントを値 arg に設定します。
2) 現在のアラインメントをデフォルト値(コマンドラインオプションで指定された値)に設定します。
3) 現在のアライメント値を内部スタックにプッシュします。
4) 内部スタックに現在のアライメント値をプッシュし、その後、現在のアライメントを値 arg に設定します。
5) 内部スタックから最上位エントリをポップし、現在のアライメントをその値に設定(復元)します。

#pragma pack はクラスのアライメントを減少させる可能性がありますが、クラスをオーバーアラインさせることはできません。

詳細については、以下の GCC および MSVC のドキュメントも参照してください。

参考文献

  • C++23標準 (ISO/IEC 14882:2024):
  • 15.9 プラグマ指令 [cpp.pragma]
  • C++20規格 (ISO/IEC 14882:2020):
  • 15.9 プラグマ指令 [cpp.pragma]
  • C++17標準 (ISO/IEC 14882:2017):
  • 19.6 プラグマ指令 [cpp.pragma]
  • C++14 標準 (ISO/IEC 14882:2014):
  • 16.6 プラグマ指令 [cpp.pragma]
  • C++11標準 (ISO/IEC 14882:2011):
  • 16.6 プラグマ指令 [cpp.pragma]
  • C++98標準 (ISO/IEC 14882:1998):
  • 16.6 プラグマ指令 [cpp.pragma]

関連項目

C documentation for Implementation defined behavior control

外部リンク

1. Visual Studio における C++ プラグマ
2. プラグマ GCC で受け入れられるプラグマ
3. 個別プラグマの説明 および 標準プラグマ IBM AIX XL C 16.1
4. 付録 B. プラグマ Sun Studio 11 C++ ユーザーズガイド
5. Intel C++ コンパイラのプラグマ
6. リリースノート(プラグマを含む) HP aCC A.06.25