Most vexing parse

Most vexing parse

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).[1] It is formally defined in section 6.8 of the C++ language standard.[2]

Contents

Example with classes

An example is:

class Timer {
 public:
  Timer();
};
 
class TimeKeeper {
 public:
  TimeKeeper(const Timer& t);
 
  int get_time();
};
 
int main() {
  TimeKeeper time_keeper(Timer());
  return time_keeper.get_time();
}

The line

  TimeKeeper time_keeper(Timer());

could be disambiguated either as

  1. a variable definition for variable time_keeper of class TimeKeeper, taking an anonymous instance of class Timer or
  2. a function declaration for a function time_keeper which returns an object of type TimeKeeper and takes a single (unnamed) argument which is a 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:

$ g++ -c time_keeper.cc
time_keeper.cc: In function ‘int main()’:
time_keeper.cc:15: error: request for member ‘get_time’ in ‘time_keeper’, which is
  of non-class type ‘TimeKeeper(Timer (*)())’

Clang++ provides a useful warning:

$ clang++ time_keeper.cc
time_keeper.cc:14:25: warning: parentheses were disambiguated as a function declarator
  TimeKeeper time_keeper(Timer());
                        ^~~~~~~~~


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

  TimeKeeper time_keeper( (Timer()) );

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

void f(double adouble) {
  int i(int(adouble));
}

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

// takes an integer and returns an integer
int i(int adouble);

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 to use a named cast

// declares a variable called 'i'
int i(static_cast<int>(adouble));

Uniform initialization syntax

Using the new uniform initialization syntax introduced in C++0x/C++11 solves this issue (and many more headaches related to initialization styles in C++).

The problematic code is then unambiguous when braces are used:

  TimeKeeper time_keeper{Timer()};

References

  1. ^ Meyers, Scott (2001). Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library. Addison-Wesley. ISBN 0201749629. 
  2. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §6.8 Ambiguity resolution [stmt.ambig]

Wikimedia Foundation. 2010.

Игры ⚽ Поможем написать реферат

Look at other dictionaries:

  • C++11 — C++11, also formerly known as C++0x,[1] is the name of the most recent iteration of the C++ programming language, replacing C++TR1, approved by the ISO as of 12 August 2011.[2] The name is derived from the tradition of naming language versions by …   Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”