开发者

GCC's two unusual error messages

Today, I came across two error messages which I never seen before. It's completely new to me.

Here is the code:

template<typename T>
struct adder { adder(const T &item) { } };

template<typename T>
void initializer(const T &item) {  adder<T>(item); }

int main() 
{
   initializer("const string literal");
}

On compiling, GCC gives these errors:

prog.cpp: In function ‘void initializer(const T&)’:

prog.cpp:6: error: declaration of ‘adder<T> item’ shadows a parameter

prog.cpp: In function ‘void initializer(const T&) [with T = char [21]]’:

prog.cpp:10: instantiated from here

prog.cpp:6: error: declaration of ‘adder<char [21]> item’ shadows a parameter

prog.cpp:6: error: no matching function for call to ‘adder<char [21]>::adder()’

prog.cpp:3: note: candidates are: adder<T>::adder(const T&) [with T = char [21]]

prog.cpp:3: note: adder<char [21]>::adder(const adder<char [21]>&)


See the bold text. One error is sho开发者_JAVA百科wn twice, which is this

error: declaration of ‘adder<T> item’ shadows a parameter

error: declaration of ‘adder<char [21]> item’ shadows a parameter

What does it mean? Why does it show twice with different template arguments? First one with T, second one with char [21]?

EDIT: does adder<T>(item) declare variable with name item? But that is not what I intended. I think it should create a temporary object passing item as argument to the constructor.

I would like to know the section from the Standard which deals with this issue!


Other interesting error is this:

error: no matching function for call to ‘adder<char [21]>::adder()’

Which indicates that the compiler is looking for default constructor? But I'm wondering why is the compiler looking for it when in fact my code doesn't use it at line 6?


Code at ideone : http://www.ideone.com/jrdLL


Which indicates that the compiler is looking for default constructor? But I'm wondering why is the compiler looking for it when in fact my code doesn't use it at line 6?

Because compiler think that you declare local variable with name item.

http://codepad.org/YBPKCvmm


The key to understanding what is happening is to realize that: adder(item); is a definition of a local variable named item and having type adder; the parentheses are superfluous, but perfectly permissable. If you want to call the constructor, you'll have to disambiguate, by writing it in some way that cannot be interpreted as a data definition, say: adder((item)); (I'm not sure what use this may be. It constructs a temporary object of adder, then destructs it at the end of the expression.)

The actual error messages should be clear(er) once the statement is understood as a data declaration: function parameters are treated as if they were defined in the top level block of the function, so adder(item) is a duplicate (and contradictory) definition, and adder doesn't have a default constructor, so you can't define an instance of it without providing arguments.


I only have access to the C++0x draft at the moment, so I can't give you the current chapter and verse, but I don't think much has changed. In 0x it's in section 6.8 - Ambiguity Resolution:

There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.

[...]

T(a); // declaration

That is, a declaration of a variable named "a" of type T.

If your adder<T>(item) were to define a temporary (un-named) object, it would be an expression-statement, but if something can be parsed as either a declaration-statement or an expression-statement, C++ parses it as a declaration-statement.

[...] the resolution is to consider any construct that could possibly be a declaration a declaration. (8.2)

In other words, it's a cousin to everyone's dear old friend, the Most Vexing Parse.

Update: I looked at ambiguity resolution in C++03, and those passages are identical.


"shadowing" means that two objects have the same name, which the language allows at this point, but might not be intended.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜