>백엔드 개발 >C++ >MSVC의 2단계 템플릿 인스턴스화가 C 표준에서 벗어나는 이유는 무엇입니까?

MSVC의 2단계 템플릿 인스턴스화가 C 표준에서 벗어나는 이유는 무엇입니까?

Linda Hamilton
Linda Hamilton원래의
2024-12-24 14:06:15182검색

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

Microsoft Visual C의 2단계 템플릿 인스턴스화: 문제점은 무엇입니까?

Microsoft Visual C(MSVC)는 다음과 같은 주장으로 비판을 받았습니다. 2단계 템플릿 인스턴스화의 잘못된 구현. C 표준에 정의된 이 방법론은 두 가지 단계로 구성됩니다.

첫 번째 단계:

  • 기본 구문 및 유형 검사를 수행합니다.
  • 내에서 사용된 비종속 이름의 선언이나 존재를 확인하지 않습니다. template.

두 번째 단계:

  • 비종속 이름을 확인하고 해당 선언에 바인딩합니다.
  • 네임스페이스 조회 확장 첫 번째 이후 누적된 선언이 있는 종속 이름의 경우 Phase.

MSVC의 결함:

MSVC의 주요 문제는 비종속 표현식에 대한 초기(1단계) 조회를 수행하지 못한다는 것입니다. 대신 두 번째 단계까지 모든 조회를 연기하므로 잘못된 동작이 발생합니다. 또한 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의 2단계 템플릿 인스턴스화가 C 표준에서 벗어나는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.