To install click the Add extension button. That's it.

The source code for the WIKI 2 extension is being checked by specialists of the Mozilla Foundation, Google, and Apple. You could also do it yourself at any point in time.

4,5
Kelly Slayton
Congratulations on this excellent venture… what a great idea!
Alexander Grigorievskiy
I use WIKI 2 every day and almost forgot how the original Wikipedia looks like.
Live Statistics
English Articles
Improved in 24 Hours
Added in 24 Hours
Languages
Recent
Show all languages
What we do. Every page goes through several hundred of perfecting techniques; in live mode. Quite the same Wikipedia. Just better.
.
Leo
Newton
Brights
Milds

Most vexing parse

From Wikipedia, the free encyclopedia

The most vexing parse is a counterintuitive form of syntactic ambiguity resolution in the C++ programming language. In certain situations, the C++ grammar cannot distinguish between the creation of an object parameter and specification of a function's type. In those situations, the compiler is required to interpret the line as a function type specification.

YouTube Encyclopedic

  • 1/5
    Views:
    56 757
    7 859
    54 008
    175 171
    189 672
  • CppCon 2018: Timur Doumler “Can I has grammar?”
  • CppCon 2018: Timur Doumler & Dmitry Kozhevnikov “Parsing C++”
  • CppCon 2018: Nicolai Josuttis “The Nightmare of Initialization in C++”
  • Thread Management | Advanced C++: Multithreading & Multiprocessing for Firmware Systems #2
  • Sponsorship Proposal Basics in About 15 Minutes

Transcription

Occurrence

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]

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) {
  int i(int(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 {
  explicit TimeKeeper(Timer t);
  int get_time();
};

int main() {
  TimeKeeper time_keeper(Timer());
  return time_keeper.get_time();
}

The line

  TimeKeeper time_keeper(Timer());

is ambiguous, since it could be interpreted either as

  1. a variable definition for variable time_keeper of class TimeKeeper, initialized with an anonymous instance of class Timer or
  2. a function declaration for a function time_keeper that returns an object of type TimeKeeper and has a single (unnamed) parameter, whose type is a (pointer to a) function[Note 1] taking no input and returning Timer objects.

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:[3]

$ clang++ time_keeper.cc
timekeeper.cc:9:25: warning: 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: error: 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.[4][5] 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"

// declares a variable of type int
int i((int)my_dbl);

or a named cast:

int i(static_cast<int>(my_dbl));

In the variable declaration example, the preferred method (since C++11) is uniform (brace) initialization.[6] This also allows limited omission of the type name entirely:

//Any of the following work:
TimeKeeper time_keeper(Timer{});
TimeKeeper time_keeper{Timer()};
TimeKeeper time_keeper{Timer{}};
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:[5]

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.[7] Since C++17, this optimization is guaranteed.[8]

Notes

  1. ^ 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++.

References

  1. ^ Meyers, Scott (2001). Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library. Addison-Wesley. ISBN 0-201-74962-9.
  2. ^ 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.
  3. ^ 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.
  4. ^ 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.
  5. ^ a b Boccara, Jonathan (2018-01-30). "The Most Vexing Parse: How to Spot It and Fix It Quickly". Fluent C++. Retrieved 2021-01-17.
  6. ^ Stroustrup, Bjarne (19 August 2016). "C++11 FAQ". www.stroustrup.com. Uniform initialization syntax and semantics. Retrieved 2021-01-17.
  7. ^ "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.
  8. ^ Devlieghere, Jonas (2016-11-21). "Guaranteed Copy Elision". Jonas Devlieghere. 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. Retrieved 2021-01-17.

External links

This page was last edited on 1 June 2024, at 17:59
Basis of this page is in Wikipedia. Text is available under the CC BY-SA 3.0 Unported License. Non-text media are available under their specified licenses. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc. WIKI 2 is an independent company and has no affiliation with Wikimedia Foundation.