Most vexing parse with array access

While looking at some C++03 code, I found an instance of the most vexing parse that confused me:

#include <sstream>
#include <string>

int main(int, char** argv)
    std::stringstream ss(std::string(argv[0]));

live example on wandbox

In the snippet above, ss is a declaration to a function that takes a std::string* and returns std::stringstream.

How is std::string(argv[0]) being parsed as std::string*?

Intuitively I thought that argv[0] was unambiguously an access to argv.


The reason is because in the context of a function declaration, the compiler will interpret std::string(argv[0]) as std::string argv[0], i.e. a declaration of a zero-sized array as the function parameter named argv (overshadowing the argv from main, as this is a different scope), which then is equivalent to a pointer by array-to-pointer-decay.

Therefore, std::stringstream ss(std::string(argv[0])); means the same as std::stringstream ss(std::string* argv);

Edit: As it got correctly annotaded in the comments, zero-sized array declarations are invalid in C++, rendering the program ill-formed. When compiling this code with -pedantic flags (GCC and clang), warnings will be issued. Visual Studio even produces a compilation error. For any other array index than 0, the argumentation above however still holds.

I believe this follows from the "declaration syntax is like expression syntax" principle, and the fact that "array" parameters are pointers.

The following array declarations are equivalent:

int x[1];
int (x)[1];
int (x[1]);

more or less because x[a], (x)[a], and (x[a]) are equivalent expressions.


std::stringstream ss(std::string(argv[0]))


std::stringstream ss(std::string argv[0])


std::stringstream ss(std::string* argv)

Need Your Help

java.rmi.ConnectException: Connection refused to host:;

java exception connection rmi remoteobject

java.rmi.ConnectException: Connection refused to host:; nested exception is:

What does multicore assembly language look like?

assembly x86 cpu multicore smp

Once upon a time, to write x86 assembler, for example, you would have instructions stating "load the EDX register with the value 5", "increment the EDX" register, etc.