Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 221
Vittorio Romeo Avatar asked Dec 12 '17 15:12

Vittorio Romeo


2 Answers

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.

like image 57
Jodocus Avatar answered Nov 10 '22 08:11

Jodocus


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.

Thus,

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

                 <=>

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

                 <=>

std::stringstream ss(std::string* argv)
like image 32
molbdnilo Avatar answered Nov 10 '22 06:11

molbdnilo