首頁 > 後端開發 > C++ > 為什麼MSVC的兩階段模板實例化偏離C標準?

為什麼MSVC的兩階段模板實例化偏離C標準?

Linda Hamilton
發布: 2024-12-24 14:06:15
原創
182 人瀏覽過

Why Does MSVC's Two-Phase Template Instantiation Deviate from the C   Standard?

Microsoft Visual C 中的兩階段範本實例化:問題是什麼?

Microsoft Visual C (MSVC) 因其所謂的兩階段範本實例化的錯​​誤實現。此方法由 C 標準定義,由兩個不同的階段組成:

第一階段:

  • 執行基本語法和類型檢查。
  • 不驗證內部使用的非依賴名稱的宣告或存在範本。

第二階段:

  • 解析非依賴名稱並將其綁定到其聲明。
  • 擴展命名空間查找對於具有自第一個以來累積的聲明的從屬名稱

MSVC 的缺陷:

MSVC 的主要問題在於它無法對非依賴表達式執行早期(第一階段)查找。相反,它將所有查找推遲到第二階段,從而導致不正確的行為。此外,MSVC 的第二階段未正確遵循非 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 在第二階段錯誤地將其綁定到 'foo(int)',導致初始化期間出錯。

額外的不正確層:

即使在初始化期間第二階段,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 )' 應該解析為'void bar(void )',儘管在第二階段得到了解決。然而,MSVC 錯誤地將其解析為“void bar(N::S s)”,這表明其實作是錯誤的。

結論:

MSVC 的兩個-階段模板實例化實現未能完全遵守C 標準,導致在處理非依賴表達式和非ADL 查找時出現不正確的行為。這些缺陷可能會導致意外的編譯時錯誤和程式行為。

以上是為什麼MSVC的兩階段模板實例化偏離C標準?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板