Visual C++ 2005 コンパイラの互換性に影響する変更点
更新 : 2007 年 11 月
このトピックでは、以前のリリースで動作していたコードがコンパイルできなくなるか、または実行時の動作が異なる原因になる Visual C++ 2005 の動作の変更について説明します。
新しい機能の詳細については、「Visual C++ 2005 とそれ以前のエディションの変更点」、「Visual C++ 2005 ライブラリの変更点」、および「Visual C++ 2005 コンパイラ、言語、およびツールの変更」を参照してください。
メンバへのポインタに修飾名と & が必要になりました
メソッド名のみを使用した以前のバージョンのコンパイラ用に記述されたコードでは、コンパイラ エラー C3867 またはコンパイラの警告 C4867 が生成されるようになりました。この診断は、標準 C++ により必要とされます。メンバ関数へのポインタを作成するには、アドレス演算子 (&) をメソッドの完全修飾名と同時に使用することが必要になりました。& 演算子とメソッドの完全修飾名を使用しないと、関数呼び出しでかっこが見つからないことが原因で、コードに論理バグが発生する可能性があります。引数リストなしで関数の名前を使用すると、複数の種類に変換可能な関数ポインタが発生します。このコードをコンパイルすると、実行時に予期しない動作が発生することがあります。クラスは、フレンド宣言にアクセスできる必要があります
Visual C++ 2005 以前の Visual C++ コンパイラでは、宣言を含むクラスのスコープ内でアクセスできないクラスへのフレンド宣言を使用できました。現在のバージョンでは、コンパイラによりコンパイラ エラー C2248 が生成されるようになりました。このエラーを解決するには、フレンド宣言で指定されたクラスのアクセシビリティを変更します。この変更は、C++ 標準に準拠するために加えられました。__int asm 3 がネイティブにコンパイルされるようになりました
/clr を使用してコンパイルすると、__asm int 3 によりネイティブ コードは生成されず、コンパイラは命令を CLR 中断命令に変換していました。Visual C++ 2005 では、__asm int 3 により関数用のネイティブ コードが生成されます。関数によりコードにブレークポイントを生成する場合や、関数を MSIL にコンパイルする場合は、__debugbreak を使用します。詳細については、「__asm」および「/clr (共通言語ランタイムのコンパイル)」を参照してください。この変更は、マネージ コードに対してネイティブ コードを生成するとき、インライン アセンブリ コードによりネイティブ コードが生成されることをより確実にするために加えられました。コピー コンストラクタおよびコピー代入演算子に明示的な特化を使用できません
コピー コンストラクタまたはコピー代入演算子の明示的なテンプレート特化に依存するコードでは、コンパイラ エラー C2299 が生成されるようになりました。標準 C++ では、この使用が禁止されています。この変更は、標準に準拠して、コードの移植性を向上するために加えられました。特化されていないクラス テンプレートは、基本クラス リストのテンプレート引数として使用できません
クラス定義用の基本クラス リスト内にある特化されていないテンプレート クラス名を使用すると、コンパイラ エラー C3203 が生成されます。特化されていないテンプレート クラス名を、基本クラス リストでテンプレート パラメータとして使用することはできません。基本クラス リストでテンプレート パラメータとしてテンプレート クラスを使用する際は、テンプレート型パラメータをテンプレート クラスに明示的に追加します。この変更は、標準に準拠して、コードの移植性を向上するために加えられました。入れ子にされた型の宣言を使用することはできなくなりました
入れ子にされた型の宣言を使用するコードでは、コンパイラ エラー C2885 が生成されるようになりました。解決するには、入れ子にされた型への参照を完全に修飾するか、名前空間に型を配置するか、または typedef を作成する必要があります。この変更は、標準に準拠して、コードの移植性を向上するために加えられました。コンパイラが /clr:oldSyntax で const_cast のダウン キャストを許可しません
Visual C++ 2005 以前では、Visual C++ コンパイラは C++ マネージ拡張構文を使用するソース コードをコンパイルするときに、const_cast Operatorのダウン キャストを許可していました。現在のバージョンでは、const_cast を使用してダウン キャストを実行すると、コンパイラ エラー C2440 が生成されるようになりました。解決するには、正しいキャスト演算子を使用します。詳細については、「Casting Operators」を参照してください。この変更は、標準に準拠するために加えられました。コンパイラで、マネージ列挙型の事前宣言を使用できません
Visual C++ 2005 以前では、Visual C++ コンパイラでマネージ列挙型の事前宣言を使用できました。現在のバージョンでは、/clr の形式を使用してコンパイルするときに、マネージ列挙型を宣言するだけで定義しないと、コンパイラ エラー C2599 が生成されます。解決するには、必ず宣言時にマネージ列挙型を定義します。この変更は、マネージ列挙型の事前宣言が必ずしも正しく機能するとは限らないために加えられました。コンパイラは列挙型の基になる型を正しく特定できません。C++ 標準でも、列挙型の宣言が許可されません。/YX コンパイラ オプションが削除されました
/YX により、自動プリコンパイル済みヘッダーをサポートしていました。このオプションは、開発環境で既定で使用されていました。/YX をビルド構成から削除するだけで置き換えをしない場合は、ビルドが高速になります。/YX を使用すると予期しない動作が発生する可能性があります。また、/Yc (プリコンパイル済みヘッダー ファイルの作成) および /Yu (プリコンパイル済みヘッダー ファイルの使用) は、プリコンパイル済みヘッダーの用途をより細かく制御できるので、こちらを使用する方が適切です。/Oa および /Ow コンパイラ オプションが削除されました
/Ow および /Oa コンパイラ オプションは削除されましたが、自動的に無視されます。コンパイラがエイリアスを使用する方法を指定するには、noalias 修飾子または restrict__declspec 修飾子を使用してください。/Op コンパイラ オプションが削除されました
/Op コンパイラ オプションが削除されました。代わりに、/fp (浮動小数点の動作の指定) を使用してください。/ML および /MLd コンパイラ オプションが削除されました
Visual C++ では、静的にリンクされた、シングルスレッドの CRT ライブラリがサポートされなくなりました。代わりに、/MT および /MTd を使用してください。詳細については、「C ランタイム ライブラリ」を参照してください。/G3、/G4、/G5、/G6、/G7、および /GB の各コンパイラ オプションが削除されました
コンパイラでは、すべてのアーキテクチャに最適な出力ファイルの作成を試みる、融合されたモデルが使用されるようになりました。/Gf が削除されました
代わりに /GF (同一文字列の削除) を使用します。/GF は、プールされた文字列を読み取り専用セクションに配置します。これは、/Gf がそれらの文字列を追加する書き込み可能セクションより安全です。/clr は /MT と互換性がありません
C ランタイム ライブラリでは、マネージ アプリケーションへの静的リンクがサポートされません。すべてのマネージ アプリケーションは、動的にリンクする必要があります (/MD)。/clr を使用する場合の制限の詳細については、「/clr の制約」を参照してください。/GS は既定でオンになりました
バッファ オーバーフローのチェックが、既定で有効になりました。/GS- を使用すると、バッファ オーバーフローのチェックを無効にできます。詳細については、「/GS (バッファのセキュリティ チェック)」を参照してください。/Zc:wchar_t は既定でオンになりました
これは、標準 C++ の動作です。wchar_t 変数は、短い符号なし整数の代わりに組み込み型が既定になります。この変更により、クライアント コードが、/Zc:wchar_t (LNK2019) を使用せずにコンパイルされたライブラリとリンクしている場合は、バイナリ互換性がなくなります。その場合、/Zc:wchar_t- を使用して、標準の動作ではない以前の動作に戻します。この変更は、準拠したコードを既定で作成するために加えられました。詳細については、「/Zc:wchar_t (wchar_t をネイティブ型として認識)」を参照してください。
/Zc:forScope は既定でオンになりました
これは、標準 C++ の動作です。for ループ スコープが終了した後に for ループで宣言された変数の使用に依存しているコードは、コンパイルに失敗するようになりました。/Zc:forScope- を使用して、標準の動作ではない以前の動作に戻します。この変更は、準拠したコードを既定で作成するために加えられました。詳細については、「/Zc:forScope (for ループのスコープの強制準拠)」を参照してください。
Visual C++ 属性のパラメータ チェックを強制的に実行します
型が文字列ではない場合は引用符で囲まれ、型が文字列の場合は引用符がない属性コンストラクタに名前付き属性を渡すコードでは、コンパイラ エラー C2065 またはコンパイラの警告 (レベル 1) C4581 が生成されるようになりました。以前は、すべてのコンパイラ属性が文字列として解析され、必要な場合は不足している引用符をコンパイラが挿入していました。属性サポートは、パラメータ チェック検査を追加することにより強化されました。これにより、属性コンストラクタに渡される間違った引数が原因で発生する、予期しない動作が回避されます。現在のリリースでは、文字列が引用符で囲まれている場合でも、暗黙的な文字列を引数として使用する属性に渡す引数に、マルチバイト文字列 (MBCS) を使用することができません (使用すると、.idl ファイルが破損する可能性があります)。代替手段は次のとおりです。
#define ARG string_with_MBCS_chars [helpstring(ARG)]
コンパイラでは、同じ型の複数の宣言に同じテンプレート仕様が必要になりました
ある型の事前宣言を行って、その型のフレンドを作成できるようにした場合、たとえばその型のテンプレート仕様はその型のすべての宣言で同じにする必要があります。同じにしない場合、コンパイラによりコンパイラ エラー C2990 が生成されます。uuid 属性がマネージ型を対象にすることができなくなりました
uuid (C++ 属性) 属性は、C++ マネージ拡張を使用してユーザー定義属性で使用できましたが、コンパイラ エラー C3451 が生成されるようになりました。代わりに、GuidAttribute を使用してください。カスタム属性にマネージ配列を渡す構文が変更されました
配列の型が、集約の初期化リストから推測されなくなりました。コンパイラでは、配列の型と初期化子リストの指定が要求されるようになりました。古い構文を使用すると、コンパイラ エラー C3104 が生成されるようになりました。この変更は、コンパイラが集計の初期化リストから配列の型を常に正しく推測できるとは限らないため必要でした。コンパイラが、宣言内の既定の型として int を挿入しなくなりました
宣言内に型がないコードの既定は、int 型ではなくなりました。コンパイラにより、コンパイラの警告 C4430 またはコンパイラの警告 (レベル 4) C4431 が生成されます。標準 C++ では、既定の int がサポートされません。この変更は、実際に必要な型を確実に取得するのに役立ちます。dynamic_cast の C++ 標準への準拠が強化されました
C ランタイム ライブラリは、dynamic_cast ランタイム チェックを行って、キャストである式のコンパイル時の型が、キャスト対象の型 (ダウンキャストの場合) または最派生オブジェクトの型 (クロスキャストの場合) のどちらかのパブリック基本クラス サブ オブジェクトを参照していることを確認します。詳細については、「dynamic_cast の互換性に影響する変更点」を参照してください。rvalue は非 const 参照にバインドできません
rvalue は非 const 参照にバインドできません。以前のバージョンの Visual C++ では、直接的な初期化処理で rvalue を非 const 参照にバインドできました。このコードにより、コンパイラの警告 (レベル 1) C4350 が生成されるようになりました。値型により既定のコンストラクタが生成されなくなったため、型初期化子がさまざまな位置で実行される可能性があります
Visual C++ 2005 以前では、値型のインスタンスが作成されると値型の静的コンストラクタ (型初期化子) が実行されました。静的コンストラクタが確実に実行されるようにするには、静的データ メンバ (/clr:oldSyntax のみ) にアクセスするか、インスタンス コンストラクタを定義します。共通言語ランタイムは常に既定のコンストラクタを呼び出すことを保証しないため、値型の既定のコンストラクタは生成されませんでした。値型の既定のコンストラクタを生成しないと、パフォーマンスが向上します。ボックス化変換された型が、検証可能な (/clr:safe) コンテキストでのみ読み取り専用になりました
共通言語ランタイムでは、検証可能なアセンブリをコンパイルするときに、ボックス化変換された型を変更することができなくなりました。変更が検出されると、コンパイラによりコンパイラの警告 C4972 が生成されます。C4792 は、ボックス化変化されたオブジェクトを使用して、基になる値オブジェクトの値を変更した場合にのみ生成されます。値オブジェクトのコピーを変更した場合 (たとえば、ボックス化変換されたオブジェクトを変更するなど)、エラーは発生しません。
ネイティブ型はアセンブリの外側では既定でプライベートになりました
ネイティブ型は、アセンブリの外側では既定で表示されなくなりました。アセンブリの外側での型の表示の詳細については、「Type Visibility」を参照してください。この変更はもともと、大文字と小文字を区別しない他の言語を使用する開発者が、Visual C++ で記述されたメタデータを参照するときに必要とするために加えられました。/clr が Visual C++ の新しい CLR 構文を受け入れるようになりました
Visual C++ 2005 以前では、/clr が C++ マネージ拡張構文をコンパイルしていました。現在のバージョンでは、/clr は新しい CLR 構文をコンパイルするようになり、/clr:oldSyntax が C++ マネージ拡張構文をコンパイルします。/clr の詳細については、「/clr (共通言語ランタイムのコンパイル)」を参照してください。新しい構文の詳細については、「New C++ Language Features」を参照してください。/clr が C ソース コード ファイルをコンパイルしなくなりました
Visual C++ 2005 以前では、/clr を使用して C ソース コード ファイルをコンパイルできましたが、現在ではコマンド ライン エラー D8045 が生成されるようになりました。解決するには、ファイル拡張子を .cpp または .cxx に変更するか、/TP または /Tp を使用してコンパイルします。詳細については、「/Tc、/Tp、/TC、/TP (ソース ファイル タイプの指定)」を参照してください。等価性テスト時に MSIL が変更されます
詳細については、「方法 : 等価性をテストする」を参照してください。