Home > Backend Development > C++ > Why Does MSVC's Two-Phase Template Instantiation Deviate from the C Standard?

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

Linda Hamilton
Release: 2024-12-24 14:06:15
Original
182 people have browsed it

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

Two-Phase Template Instantiation in Microsoft Visual C : What's the Issue?

Microsoft Visual C (MSVC) has been criticized for its alleged incorrect implementation of two-phase template instantiation. This methodology, as defined by the C standard, consists of two distinct phases:

First Phase:

  • Performs basic syntax and type checking.
  • Does not verify the declaration or existence of non-dependent names used within templates.

Second Phase:

  • Resolves and binds non-dependent names to their declarations.
  • Extends the namespace lookup for dependent names with declarations accumulated since the first phase.

MSVC's Deficiencies:

MSVC's primary issue lies in its failure to perform early (first phase) lookup for non-dependent expressions. Instead, it defers all lookup until the second phase, leading to incorrect behavior. Additionally, MSVC's second phase does not correctly respect the specification for non-ADL lookup, which should not be extended during this phase.

Example:

Consider the following code:

int foo(void*);

template<typename T> struct S {
  S() { int i = foo(0); }
};

void foo(int);

int main() {
  S<int> s;
}
Copy after login

A standard-compliant compiler should bind the 'foo(0)' call to 'foo(void*)' during the first phase. However, MSVC incorrectly binds it to 'foo(int)' during the second phase, resulting in an error during initialization.

Additional Layer of Incorrectness:

Even during the second phase, MSVC fails to adhere to the standard's stipulation that non-ADL lookup should not be extended. This results in the inclusion of declarations that were not available during the first phase, leading to unexpected behavior.

Example:

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);
}
Copy after login

Here, 'bar(t)' should resolve to 'void bar(void ),' despite being resolved during the second phase. Yet, MSVC incorrectly resolves it to 'void bar(N::S s),' demonstrating its faulty implementation.

Conclusion:

MSVC's two-phase template instantiation implementation fails to fully adhere to the C standard, resulting in incorrect behavior when dealing with both non-dependent expressions and non-ADL lookup. These deficiencies can lead to unexpected compile-time errors and program behavior.

The above is the detailed content of Why Does MSVC's Two-Phase Template Instantiation Deviate from the C Standard?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template