GCC (8.3, 9.1), Clang (7, 8) and MSVC (19.20) differ is their ability to compile this code:
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 and MSVC accept it, whereas Clang rejects it. Clang rejects it even if I make foo
itself a template and/or do not call it at all.
My understanding is that foo
is not instantiated unless it is called, and it is instantiated at the point where it is called. At that point C
is complete, and the code should compile. Is this a reasoning of GCC?
As a side note, if foo
is not called, MSVC accepts the code even if I replace C
with an undeclared C2
inside foo
- in this case it seems to just check the function body to be syntactically correct.
Which behaviour is correct according to the Standard? If it is Clang's, why does the Standard forbids the flexibility that GCC gives?