Why is the compiler not warning about definitions with no names?
The following C++ code does nothing (using GCC 4.4.3) - it does not print the text:
struct MyStruct { MyStruct() { cout << "Hello" << endl; } };
void foo() {
开发者_开发问答 MyStruct ();
}
I think this is not so obvious... Let alone the danger of forgetting to give a variable name. Is there a compiler option/warning to forbid compilation of such code or is there any hidden secret behind allowing it?
Edit: I am sorry. The version above MyStruct();
acutally prints. The version which is not printing is:
void bar() {
MyStruct a();
}
So now I am a bit confused.
This is not a declaration, because in MyStruct ();
, the MyStruct
would be part of the decl-specifier-seq and forms a type-name therein. And then ()
can only be a function-declarator. This requires that there is a declarator-id specified, which in your case is not. A special syntactical form is needed to allow such a syntax in declaring a constructor. But such syntactical exceptions are not made in a declaration-statement.
So this construct cannot be a declaration. It is parsed as an expression which specifies a functional cast creating a temporary of type MyStruct
.
If the compiler does not print Hello it is either non-conforming or you are not calling foo
in your program.
Your edit also does not specify a declaration without a name. It instead specifies a declaration that does have a name. It declares a function that is called a
. The compiler has no way that you meant something else by this.
MyStruct a();
It could in an effort deduce this by having a recovering rule when it later discovers errors in your code such as the following
a.f();
If you have this in your code to try and call a member function and "a" is a function, the compiler could check to see if MyStruct
contains a member f
such that this expression is well-formed. But what if you just forgot to place parentheses? The following would be valid for the above declared function that returns a MyStruct
, assuming a suitably declared member f
.
a().f();
So in effect, the compiler can't really know what you mean.
You don't have "a declaration with no name" in your code. You have a completely valid expression MyStruct()
. It is not a declaration, once again, it is an expression statement. If it doesn't print anything, it mist be the effect of optimization: in C++ it is generally allowed to eliminate temporaries, even if their constructors/destructors have side effects. (Although this context is not really one where such elimination is allowed. Are you sure you actually execute that expression statement?)
MyStruct a();
declares a function a
that takes no arguments and returns a MyStruct
.
I think the temporary is elided [due to compiler optimization], hence you don't see the call to the c-tor.
Your code is syntactically perfect so there is no need for the compiler to give a warning [as such].
EDIT [As per the edits in the OP]
MyStruct a();
The above is parsed as the declaration of a function a
return a MyStruct
object and taking no parameters.
Well, temporary objects are perfectly legals. So there is no reasons to warn here.
精彩评论