/clr の制約
更新 : 2007 年 11 月
/clr の使用に関する制約を次に示します。
構造化例外ハンドラでは、/clr を指定してコンパイルする場合、_alloca の使用が制約されます。詳細については、「_alloca」を参照してください。
/clr では、ランタイム エラー チェックを使用できません。詳細については、「ネイティブ ランタイム チェックの使用方法」を参照してください。
C++ 標準構文だけを使用するプログラムを /clr を指定してコンパイルするときは、次のガイドラインがインライン アセンブリに適用されます。
ネイティブなスタック レイアウトや、現在の関数の外部の呼び出し規約、コンピュータに関するその他の低水準の情報の知識があることをインライン アセンブリ コードで想定し、その知識をマネージ関数のスタック フレームで利用すると、エラーが生じることがあります。インライン アセンブリ コードが含まれた関数は、アンマネージ関数として生成され、/clr を指定せずにコンパイルされた別のモジュール内に置かれた関数と同様に処理されます。
コピー構築された関数パラメータを渡す関数内でのインライン アセンブリ コードの使用はサポートされません。
/clr を使ってコンパイルしたプログラムから vprintf 関数 を呼び出すことはできません。
naked__declspec 修飾子は、/clr では無視されます。
_set_se_translator によって設定された変換関数は、アンマネージ コードのキャッチにだけ影響します。詳細については、「Exception Handling under /clr」を参照してください。
/clr では、関数ポインタを比較できません。
/clr では、完全にプロトタイプ宣言されていない関数を使用できません。
次のコンパイル オプションは /clr でサポートされていません。
/EHsc および /EHs。/clr は /EHa を暗黙に指定します (/EH (例外処理モデル) を参照)。
/fp:strict および /fp:except (/fp (浮動小数点の動作の指定) を参照)。
/ZI
_STATIC_CPPLIB プリプロセッサ定義 (/D_STATIC_CPPLIB) と /clr または /clr:pure コンパイラ オプションの組み合わせはサポートされていません。これは、定義によってアプリケーションが、サポートされていない静的マルチスレッドの標準 C++ ライブラリとリンクするためです。詳細については、「/MD、/MT、/LD (ランタイム ライブラリの使用)」を参照してください。
/J は /clr:safe および /clr:pure でサポートされていません。
Visual C++ 2005 では、ATL ライブラリと MFC ライブラリは純粋なモードのコンパイル (/clr:pure) でサポートされていません。/MD または /MDd を指定してコンパイルする場合は、C++ 標準ライブラリおよび CRT で /clr:pure を使用できます。
/Zi と /clr を併用すると、パフォーマンスに影響を及ぼします。詳細については、「/Z7、/Zi、/ZI (デバッグ情報の形式)」を参照してください。
ワイド文字を .NET Framework の出力ルーチンに渡すときに、/Zc:wchar_t を指定しなかったり、文字を __wchar_t にキャストしなかったりした場合、出力は unsigned short int として表示されます。次に例を示します。
Console::WriteLine(L' ') // Will output 32. Console::WriteLine((__wchar_t)L' ') // Will output a space.
#pragma unmanaged で関数が指定されている場合を除いて、/clr を指定すると /GS は無視されます。また、関数をネイティブにコンパイルする必要がある場合は、コンパイラによって警告 C4793 が生成されますが、この警告は既定ではオフになっています。
マネージ アプリケーションの関数シグネチャの要件については、「/ENTRY」を参照してください。
/openmp および /clr を指定してコンパイルされたアプリケーションは、単一の appdomain プロセスでのみ実行できます。詳細については、「/openmp (OpenMP 2.0 サポートの有効化)」を参照してください。
可変個の引数 (varargs) を受け取る関数は、ネイティブ関数として生成されます。可変個の引数位置のマネージ データ型は、ネイティブの型にマーシャリングされます。System.String 型は、実際にはワイド文字の文字列ですが、1 バイト文字の文字列にマーシャリングされます。したがって、printf の指定子が %S (wchar_t*) の場合は、代わりに %s 文字列にマーシャリングされます。
va_arg マクロを使用している場合に /clr:pure を指定してコンパイルを行うと、予期しない結果が発生することがあります。詳細については、「va_arg、va_end、va_start」を参照してください。
スタックを検索してパラメータ情報 (関数の引数) を取得する関数を、マネージ コードから呼び出さないでください。P/Invoke レイヤにより、取得された情報がスタックのさらに下に置かれます。たとえば、/clr を指定して proxy/stub をコンパイルしないでください。
関数は可能な限りマネージ コードにコンパイルされますが、すべての C++ 構成要素をマネージ コードに変換できるとは限りません。変換できるかどうかは関数ごとに決定されます。関数のいずれかの部分がマネージ コードに変換できない場合は、関数全体がネイティブ コードに変換されます。次のような場合は、マネージ コードが生成されません。
コンパイラが生成したサンクまたはヘルパ関数。関数ポインタを通じたすべての関数呼び出し (仮想関数呼び出しを含む) に対して、ネイティブなサンクが生成されます。
setjmp または longjmp を呼び出す関数。
特定の組み込みルーチンを使用してコンピュータ リソースを直接操作する関数。たとえば、__enable と __disable、_ReturnAddress と _AddressOfReturnAddress、またはマルチメディア組み込みを使用すると、関数はすべてネイティブ コードに変換されます。
#pragma unmanaged ディレクティブの後ろにある関数。逆の #pragma managed もサポートされます。
配置される型、つまり __declspec(align(...)) を使用して宣言された型の参照を含む関数。
Compiler COM Support クラスは /clr:pure または /clr:safe とは併用できません。