There is this code:
class A;
template <class T>
void fun() {
A a;
}
class A {
public:
A() { }
};
int main() {
fun<int>();
return 0;
}
g++ 4.5 and g++ 4.7 compiles this without error. But clang++ 3.2 (trunk) gives this error:
main.cpp:5:6: error: variable has incomplete type 'A'
A a;
^
main.cpp:1:7: note: forward declaration of 'A'
class A;
^
Which compiler is right then according to C++ standard?
Which compiler is right then according to C++ standard?
Both are correct. This is an ill-formed program. Emphasis mine:
N3290 14.6¶9
If a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is done, and if the completeness of that type affects whether or not the program is well-formed or affects the semantics of the program, the program is ill-formed; no diagnostic is required.
That clang++ and other compilers do issue a diagnostic here is a nice-to-have added feature, but a diagnosis is not mandatory. That clause "the program is ill-formed; no diagnostic is required" gives a compiler developer free reign to do just about anything in such circumstances and still be compliant.
Clang is correct, as far as I know. At your function fun, you do not know the size of A, and since your allocating an A, you need to know it's size. In my opinion, gcc is way to forgiving here.
clang++
is using the correct behavior, this is described in section 4.6/9
of the standard (n1905).
Templates 14.6/9 Name resolution
If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition; the name is bound to the declaration (or declarations) found at that point and this binding is not affected by declarations that are visible at the point of instantiation.
To put things in simpler terms; if the name is not dependent on a template-parameter it should be in scope where the definition is found; therefore you'll need to define A
before your definition of template<typename T> void fun ()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With