プラグマ ディレクティブと __Pragma キーワード
プラグマ ディレクティブは、コンピューター固有またはオペレーティング システム固有のコンパイラ機能を指定します。 Microsoft コンパイラに固有の __pragma キーワードにより、マクロ定義内のプラグマ ディレクティブをコーディングできます。
#pragma token-string
__pragma(token-string)
解説
C および C++ の各実装は、そのホスト コンピューターまたはオペレーティング システムに固有の機能をいくつかサポートしています。 たとえば、一部のプログラムは、データが格納されているメモリ領域、または特定の関数がパラメーターを受け取る方法を正確に制御する必要があります。 #pragma ディレクティブにより、各コンパイラが C 言語および C++ 言語の全体的な互換性を維持しながら、コンピューター固有の機能およびオペレーティング システム固有の機能を提供することが可能になります。
プラグマは、コンピューター固有つまりオペレーティング システム固有であり、通常はコンパイラごとに異なります。 プラグマは、新しいプリプロセッサ機能を提供するために、または実装定義の情報をコンパイラに提供するために、条件付きステートメントで使用できます。
token-string は、特定のコンパイラ命令と引数 (ある場合) を渡す一連の文字です。 シャープ記号 (#) は、プラグマを含む行の最初の空白以外の文字である必要があります。空白文字は、シャープ記号と単語「pragma」の間に挿入できます。 #pragma の後に、トランスレーターによりプリプロセス トークンとして解析できるテキストを記述します。 #pragma の引数は、マクロの展開の対象になります。
コンパイラで認識されないプラグマが検出されると、警告が表示され、コンパイルは続行されます。
Microsoft C および C++ コンパイラは、次のプラグマを認識します。
loop1 |
||
1. C++ コンパイラでのみサポートされています。
プラグマとコンパイラのオプション
一部のプラグマの機能はコンパイラ オプションのものと同じです。 ソース コード内のプラグマは、コンパイラ オプションで指定された動作をオーバーライドします。 たとえば、/Zp8 を指定している場合は、コードの特定のセクションのコンパイラ設定を pack でオーバーライドできます。
cl /Zp8 ...
<file> - packing is 8
// ...
#pragma pack(push, 1) - packing is now 1
// ...
#pragma pack(pop) - packing is 8
</file>
__pragma() キーワード
Microsoft 固有の仕様
コンパイラは、__pragma キーワードもサポートしています。このキーワードは #pragma ディレクティブと機能は同じですが、マクロ定義内でインラインで使用できます。 コンパイラはディレクティブ内のシャープ記号 ('#') を文字列化演算子 (#) として解釈するため、#pragma ディレクティブはマクロ定義では使用できません。
マクロでの __pragma キーワードの使用方法を次のコード例に示します。 このコードは、「コンパイラ COM サポートのサンプル」の ACDUAL サンプルの mfcdual.h ヘッダーからの抜粋です。
#define CATCH_ALL_DUAL \
CATCH(COleException, e) \
{ \
_hr = e->m_sc; \
} \
AND_CATCH_ALL(e) \
{ \
__pragma(warning(push)) \
__pragma(warning(disable:6246)) /*disable _ctlState prefast warning*/ \
AFX_MANAGE_STATE(pThis->m_pModuleState); \
__pragma(warning(pop)) \
_hr = DualHandleException(_riidSource, e); \
} \
END_CATCH_ALL \
return _hr; \
END Microsoft 固有の仕様