The term "most vexing parse" was first used by Scott Meyers in his 2001 book Effective STL.1 While unusual in C, the phenomenon was quite common in C++ until the introduction of uniform initialization in C++11.2
A simple example appears when a functional cast is intended to convert an expression for initializing a variable:
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 more elaborate example is:
The line
is ambiguous, since it could be interpreted either as
The C++ standard requires the second interpretation, which is inconsistent with the subsequent line 10 above. For example, Clang++ warns that the most vexing parse has been applied on line 9 and errors on the subsequent line 10:4
The required interpretation of these ambiguous declarations is rarely the intended one.56 Function types in C++ are usually hidden behind typedefs and typically have an explicit reference 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"
or a named cast:
In the variable declaration example, the preferred method (since C++11) is uniform (brace) initialization.7 This also allows limited omission of the type name entirely:
Prior to C++11, the common techniques to force the intended interpretation were use of an extra parenthesis or copy-initialization:8
In the latter syntax, the copy-initialization is likely to be optimized out by the compiler.9 Since C++17, this optimization is guaranteed.10
Meyers, Scott (2001). Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library. Addison-Wesley. ISBN 0-201-74962-9. 0-201-74962-9 ↩
Coffin, Jerry (29 December 2012). "c++ - What is the purpose of the Most Vexing Parse?". Stack Overflow. Archived from the original on 17 January 2021. Retrieved 2021-01-17. https://stackoverflow.com/questions/14077608/what-is-the-purpose-of-the-most-vexing-parse ↩
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++. /wiki/Function_object#In_C_and_C++ ↩
Lattner, Chris (5 April 2010). "Amazing Feats of Clang Error Recovery". LLVM Project Blog. The Most Vexing Parse. Archived from the original on 26 September 2020. Retrieved 2021-01-17. https://web.archive.org/web/20200926165432/https://blog.llvm.org/posts/2010-04-05-amazing-feats-of-clang-error-recovery/ ↩
DrPizza; Prototyped; wb; euzeka; Simpson, Homer J (October 2002). "C++'s "most vexing parse"". ArsTechnica OpenForum. Archived from the original on 20 May 2015. Retrieved 2021-01-17. https://arstechnica.com/civis/viewtopic.php?f=20&t=767929 ↩
Boccara, Jonathan (2018-01-30). "The Most Vexing Parse: How to Spot It and Fix It Quickly". Fluent C++. Archived from the original on 2021-11-25. Retrieved 2021-01-17. https://www.fluentcpp.com/2018/01/30/most-vexing-parse/ ↩
Stroustrup, Bjarne (19 August 2016). "C++11 FAQ". www.stroustrup.com. Uniform initialization syntax and semantics. Archived from the original on 2021-08-20. Retrieved 2021-01-17. https://www.stroustrup.com/C++11FAQ.html#uniform-init ↩
"Myths and urban legends about C++". C++ FAQ. What is copy elision? What is RVO?. Archived from the original on 17 January 2021. Retrieved 2021-01-17. https://isocpp.org/wiki/faq/myths#copy-elision ↩
Devlieghere, Jonas (2016-11-21). "Guaranteed Copy Elision". Jonas Devlieghere. Archived from the original on 2021-11-25. Retrieved 2021-01-17. Note, however, the caveats covered in Brand, C++ (2018-12-11). "Guaranteed Copy Elision Does Not Elide Copies". Microsoft C++ Team Blog. Archived from the original on 2021-11-25. Retrieved 2021-01-17. https://jonasdevlieghere.com/guaranteed-copy-elision/ ↩