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 tha ...
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 con ...
in his 2001 book ''
Effective STL''.
While unusual in
C, the phenomenon was quite common in C++ until the introduction of
uniform initialization
C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by ...
in
C++11
C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by ...
.
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
Variable may refer to:
* Variable (computer science), a symbolic name associated with a value and whose associated value may be changed
* Variable (mathematics), a symbol that represents a quantity in a mathematical expression, as used in many ...
i
with initial value produced by
converting
Converting companies are companies that specialize in modifying or combining raw materials such as polyesters, adhesives, silicone, adhesive tapes, foams, plastics, felts, rubbers, liners and metals, as well as other materials, to create new produ ...
my_dbl
to an
int
. However, C allows superfluous parentheses around
function parameter
In computer programming, a parameter or a formal argument is a special kind of variable used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are the values of the arguments (often ...
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
Variable may refer to:
* Variable (computer science), a symbolic name associated with a value and whose associated value may be changed
* Variable (mathematics), a symbol that represents a quantity in a mathematical expression, as used in many ...
definition for variable of class , initialized with an anonymous instance of class or
# a
function declaration
In computer programming, a function prototype or function interface is a declaration of a function that specifies the function’s name and type signature ( arity, data types of parameters, and return type), but omits the function body. While a ...
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++
Clang is a compiler front end for the C, C++, Objective-C, and Objective-C++ programming languages, as well as the OpenMP, OpenCL, RenderScript, CUDA, and HIP frameworks. It acts as a drop-in replacement for the GNU Compiler Collection (GCC), ...
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
C++17 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++17 replaced the prior version of the C++ standard, called C++14, and was later replaced by C++20.
History
Before the C++ Standards Committee fixed a 3-year rel ...
, 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