开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜