GCC (8.3, 9.1), Clang (7, 8) и MSVC (19.20) отличаются своей способностью компилировать этот код:
struct C;
template<typename T> struct S {
void foo() {
// C2 c;
C c;
}
};
class C {};
int main() {
S<int> s;
s.foo();
return 0;
}
GCC и MSVC принимают его, а Clang отвергает. Clang отклоняет его, даже если я сам создаю шаблон foo
и / или не вызываю его вообще.
Насколько я понимаю, foo
не создается, если он не вызывается, и создается в точке, где он вызывается. На этом этапе C
завершено, и код должен скомпилироваться. Это обоснование GCC?
В качестве примечания, если foo
не вызывается, MSVC принимает код, даже если я заменяю C
на необъявленный C2
внутри foo
- в этом случае, кажется, просто проверяется тело функции на быть синтаксически правильным.
Какое поведение является правильным в соответствии со Стандартом? Если это Clang, почему Стандарт запрещает гибкость, которую дает GCC?