The most vexing parse is a counterintuitive form of syntactic
ambiguity resolution
Ambiguity resolution is used to find the value of a measurement that requires modulo sampling.
This is required for pulse-Doppler radar signal processing.
Measurements
Some types of measurements introduce an unavoidable modulo operation in the ...
in the
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
programming language. In certain situations, the C++ grammar cannot distinguish between the
creation
Creation may refer to:
Religion
*''Creatio ex nihilo'', the concept that matter was created by God out of nothing
*Creation myth, a religious story of the origin of the world and how people first came to inhabit it
*Creationism, the belief that ...
of an object
parameter
A parameter (), generally, is any characteristic that can help in defining or classifying a particular system (meaning an event, project, object, situation, etc.). That is, a parameter is an element of a system that is useful, or critical, when ...
and
specification of a function's type. In those situations, the compiler is required to interpret the line as a function type specification.
Occurrence
The term "most vexing parse" was first used by
Scott Meyers
Scott Douglas Meyers (born April 9, 1959) is an American author and software consultant, specializing in the C++ computer programming language. He is known for his ''Effective C++'' book series. During his career, he was a frequent speaker at co ...
in his 2001 book ''
Effective STL''.
While unusual in
C, the phenomenon was quite common in C++ until the introduction of
uniform initialization in
C++11 C11, C.XI, C-11 or C.11 may refer to:
Transport
* C-11 Fleetster, a 1920s American light transport aircraft for use of the United States Assistant Secretary of War
* Fokker C.XI, a 1935 Dutch reconnaissance seaplane
* LET C-11, a license-build ...
.
Examples
C-style casts
A simple example appears when a functional cast is intended to convert an expression for initializing a variable:
void f(double my_dbl)
Line 2 above is ambiguous. One possible interpretation is to declare a
variable i
with initial value produced by
converting my_dbl
to an
int
. However, C allows superfluous parentheses around
function parameter declarations; in this case, the declaration of
i
is instead a function declaration equivalent to the following:
// A function named i takes an integer and returns an integer.
int i(int my_dbl);
Unnamed temporary
A more elaborate example is:
struct Timer ;
struct TimeKeeper ;
int main()
The line
TimeKeeper time_keeper(Timer());
is ambiguous, since it could be interpreted either as
# a
variable definition for variable of class , initialized with an anonymous instance of class or
# a
function declaration for a function that returns an object of type and has a single (unnamed) parameter, whose type is a (pointer to a) function
[According to C++ type decay rules, a function object declared as a parameter is equivalent to a pointer to a function of that type. See Function object#In C and C++. ] taking no input and returning objects.
The
C++ standard
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
requires the second interpretation, which is inconsistent with line 9 above. For example,
Clang++ warns that the most vexing parse has been applied on line 9 and errors on the following line:
$ clang++ time_keeper.cc
timekeeper.cc:9:25: parentheses were disambiguated as a function declaration
Wvexing-parse''
TimeKeeper time_keeper(Timer());
timekeeper.cc:9:26: note: add a pair of parentheses to declare a variable
TimeKeeper time_keeper(Timer());
timekeeper.cc:10:21: member reference base type 'TimeKeeper (Timer (*)())' is not a
structure or union
return time_keeper.get_time();
Solutions
The required interpretation of these ambiguous declarations is rarely the intended one.
Function types in C++ are usually hidden behind
typedef
typedef is a reserved keyword in the programming languages C, C++, and Objective-C. It is used to create an additional name (''alias'') for another data type, but does not create a new type, except in the obscure case of a qualified typedef of ...
s and typically have an explicit
reference
Reference is a relationship between objects in which one object designates, or acts as a means by which to connect to or link to, another object. The first object in this relation is said to ''refer to'' the second object. It is called a '' name'' ...
or
pointer qualifier. To force the alternate interpretation, the typical technique is a different object creation or conversion syntax.
In the type conversion example, there are two alternate syntaxes available for casts: the "C-style cast"
// declares a variable of type int
int i((int)my_dbl);
or a named cast:
int i(static_cast(my_dbl));
In the variable declaration example, the preferred method (since C++11) is uniform (brace) initialization. This also allows limited omission of the type name entirely:
//Any of the following work:
TimeKeeper time_keeper(Timer);
TimeKeeper time_keeper;
TimeKeeper time_keeper;
TimeKeeper time_keeper( );
TimeKeeper time_keeper;
Prior to C++11, the common techniques to force the intended interpretation were use of an extra parenthesis or copy-initialization:
TimeKeeper time_keeper( /*Avoid MVP*/ (Timer()) );
TimeKeeper time_keeper = TimeKeeper(Timer());
In the latter syntax, the
copy-initialization is likely to be
optimized out by the compiler. Since
C++17
C17, C-17 or C.17 may refer to:
Transportation
* , a 1917 British C-class submarine
Air
* Boeing C-17 Globemaster III, a military transport aircraft
* Lockheed Y1C-17 Vega, a six-passenger monoplane
* Cierva C.17, a 1928 English experimental ...
, this optimization is guaranteed.
[ Note, however, the caveats covered in ]
Notes
References
External links
* Discussion in the C++03 standard final draft (see ยง8.2 Ambiguity resolution ''
cl.ambig.res'): https://web.archive.org/web/20141113085328/https://cs.nyu.edu/courses/fall11/CSCI-GA.2110-003/documents/c++2003std.pdf
*CppReference on direct initialization (the sort vulnerable to the most vexing parse): https://en.cppreference.com/w/cpp/language/direct_initialization
{{C++ programming language
C++
Ambiguity
Articles with example C++ code