Search code examples
c++c++03most-vexing-parse

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.


Solution

  • 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.