Microsoft Visual C の 2 フェーズ テンプレートのインスタンス化 : 問題は何ですか?
Microsoft Visual C (MSVC) は次のような疑いで批判されています。 2 フェーズ テンプレートのインスタンス化の不正な実装。 C 標準で定義されているこの方法論は、次の 2 つの異なるフェーズで構成されます。
第 1 フェーズ:
第 2 フェーズ:
MSVC の欠陥:
MSVC の主な問題は、非依存式の初期 (第 1 フェーズ) ルックアップを実行できないことにあります。代わりに、すべての検索が第 2 フェーズまで延期され、誤った動作が発生します。さらに、MSVC の 2 番目のフェーズでは、非 ADL ルックアップの仕様が正しく尊重されないため、このフェーズ中に拡張すべきではありません。
例:
次のコードを考えてみましょう。 :
int foo(void*); template<typename T> struct S { S() { int i = foo(0); } }; void foo(int); int main() { S<int> s; }
標準準拠のコンパイラは、「foo(0)」呼び出しを次のようにバインドする必要があります。最初のフェーズでは「foo(void*)」。ただし、MSVC は第 2 フェーズでこれを誤って「foo(int)」にバインドし、初期化中にエラーが発生します。
追加の不正レイヤー:
初期化中でも第 2 フェーズでは、MSVC は、非 ADL ルックアップを拡張すべきではないという標準の規定を順守できません。これにより、最初のフェーズでは使用できなかった宣言が含まれることになり、予期しない動作が発生します。
例:
namespace N { struct S {}; } void bar(void *) {} template <typename T> void foo(T *t) { bar(t); } void bar(N::S *s) {} int main() { N::S s; foo(&s); }
ここでは、 'bar(t )」は、第 2 フェーズ中に解決されるにもかかわらず、「void bar(void )」に解決されるはずです。しかし、MSVC はこれを「void bar(N::S s)」と誤って解決し、その実装に欠陥があることを示しています。
結論:
MSVC の 2 つの点フェーズ テンプレートのインスタンス化の実装は C 標準に完全に準拠していないため、非依存式と非 ADL ルックアップの両方を処理するときに誤った動作が発生します。これらの欠陥により、予期しないコンパイル時エラーやプログラムの動作が発生する可能性があります。
以上がMSVC の 2 フェーズ テンプレートのインスタンス化が C 標準から逸脱しているのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。