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 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) 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++ (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