How does this declaration invoke the Most Vexing Parse?

匆匆过客 提交于 2020-01-09 11:32:25

问题


Consider the following program:

#include <fstream>

struct A {};

int main(int argc, char** argv) {
    A a(std::fstream(argv[1]));
}

Clang in C++1y mode reckons that the MVP is invoked such that a is parsed as a function declaration:

clang++ -std=c++1y -O3 -Wall -Wextra -pedantic-errors -pthread main.cpp && ./a.out

main.cpp:6:8: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]

    A a(std::fstream(argv[1]));

       ^~~~~~~~~~~~~~~~~~~~~~~

main.cpp:6:9: note: add a pair of parentheses to declare a variable

    A a(std::fstream(argv[1]));

        ^

        (                    )

I understand the MVP, but not in this instance: argv[1] is clearly an expression, and there's no type before it, so how could this line be parsed as a function declaration?

Is it that the semantic interpretation on argv[1], that would disambiguate the line as an object declaration, doesn't occur until after the compiler has already chosen to parse the line as a function declaration? Or is it a Clang bug? Or is it perfectly normal through some interpretation of the tokens argv [ 1 ] that I'm missing?


回答1:


I think it's being parsed as

A a(std::fstream argv[1]);

i.e. a function that takes in an array of 1 std::fstream, where the extra parentheses are redundant.

Of course, in reality, that array parameter decays to a pointer, so what you end up with semantically is:

A a(std::fstream* argv);



回答2:


The parens are superfluous. All of the following are the declarations:

T a;
T (a);
T ((a));
T (((a))));

so are these:

T a[1];
T (a[1]);
T ((a[1]));
T (((a[1]))));

So is this:

 A a(std::fstream(argv[1]));

which is same as:

 A a(std::fstream argv[1]);

which is same as:

 A a(std::fstream *argv);

Hope that helps.



来源:https://stackoverflow.com/questions/21624880/how-does-this-declaration-invoke-the-most-vexing-parse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!