Most Vexing Parse
   HOME

TheInfoList



OR:

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 operation, modulo sampling. This is required for pulse-Doppler radar signal processing. Measurements Some types of measurements introduce an unavoidable modulo ...
in the
C++ C++ (, pronounced "C plus plus" and sometimes abbreviated as CPP or CXX) is a high-level, general-purpose programming language created by Danish computer scientist Bjarne Stroustrup. First released in 1985 as an extension of the C programmin ...
programming language. In certain situations, the C++ grammar cannot distinguish between the
creation Creation or The Creation or Creations, may refer to: Arts and entertainment Film * ''Creation'' (1922 film), a British silent drama * ''Creation'' (unfinished film), 1931 * ''Creation'' (2009 film), about Charles Darwin Literature * ''Creation ...
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 the latter.


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 Effectiveness or effectivity is the capability of producing a desired result or the ability to produce desired output. When something is deemed effective, it means it has an intended or expected outcome, or produces a deep, vivid impression. Et ...
''. While unusual in C, the phenomenon was quite common in C++ until the introduction of
uniform initialization C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior vers ...
in
C++11 C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior vers ...
.


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 Conversion or convert may refer to: Arts, entertainment, and media * ''The Convert'', a 2023 film produced by Jump Film & Television and Brouhaha Entertainment * "Conversion" (''Doctor Who'' audio), an episode of the audio drama ''Cyberman'' * ...
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 In computer programming, a function prototype 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 function definition ...
for a function that returns an object of type and has a single (unnamed) parameter, whose type is a (pointer to a) functionAccording 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 standard may refer to: * ANSI C, C99, C11, C17, or C23, specifications of the C programming language * C standard library The C standard library, sometimes referred to as libc, is the standard library for the C (programming language), C pr ...
requires the second interpretation, which is inconsistent with the subsequent line 10 above. For example,
Clang++ Clang () is a compiler front end for the programming languages C, C++, Objective-C, Objective-C++, and the software frameworks OpenMP, OpenCL, RenderScript, CUDA, SYCL, and HIP. It acts as a drop-in replacement for the GNU Compiler Collect ...
warns that the most vexing parse has been applied on line 9 and errors on the subsequent line 10: timekeeper.cc:9:25: parentheses were disambiguated as a function declaration Wvexing-parse'' timekeeper.cc:9:26: note: add a pair of parentheses to declare a variable timekeeper.cc:10:21: member reference base type '' is not a structure or union


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 A 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 ''nam ...
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