Rahul Sharma (Editor)

Most vexing parse

Updated on
Edit
Like
Comment
Share on FacebookTweet on TwitterShare on LinkedInShare on Reddit

The most vexing parse is a specific form of syntactic ambiguity resolution in the C++ programming language. The term was used by Scott Meyers in Effective STL (2001). It is formally defined in section 8.2 of the C++ language standard.

Contents

Example with classes

An example is:

The line

is seemingly ambiguous, since it could be interpreted either as

  1. a variable definition for variable time_keeper of class TimeKeeper, initialized with an anonymous instance of class Timer or
  2. a function declaration for a function time_keeper which returns an object of type TimeKeeper and has a single (unnamed) parameter which is a pointer to function returning type Timer (and taking no input). (See Function object#In C and C++)

Most programmers expect the first, but the C++ standard requires it to be interpreted as the second.

For example, g++ gives the following error message:

Notice that the compiler gives the error message about the return statement of main(): since it interpreted the declaration of time_keeper as a function declaration we won't be able to call the member function get_time() on this.

Clang++ provides a warning:

$ clang++ time_keeper.cc timekeeper.cc:14:25: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse] TimeKeeper time_keeper(Timer()); ^~~~~~~~~ timekeeper.cc:14:26: note: add a pair of parentheses to declare a variable TimeKeeper time_keeper(Timer()); ^ ( ) timekeeper.cc:15:21: error: member reference base type 'TimeKeeper (Timer (*)())' is not a structure or union return time_keeper.get_time(); ~~~~~~~~~~~^~~~~~~~~

One way to force the compiler to consider this as a variable definition is to add an extra pair of parentheses:

Example with functions

An even simpler example appears when a functional cast is intended to convert an expression for initializing a variable or passing to a constructor parameter

In this case, the parentheses around "adouble" are superfluous and the declaration of "i" is again a function declaration equivalent to the following

To disambiguate this in favour of a variable declaration, the same technique can be used as for the first case above. Another solution is to use the cast notation:

Or also to use a named cast:

Uniform initialization syntax

Using the new uniform initialization syntax introduced in C++11 solves this issue.

The problematic code is then unambiguous when braces are used:

References

Most vexing parse Wikipedia