Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why did expression types change in C++ between versions?

I try to understand expression types of C++ and the more I read, the more confused I was, since I find the C++ draft very difficult to digest and therefore prefer other resources but they either contradict each other or don't take into account that the wording and definition between C++ versions heavily changes.

In the following I refer to the following drafts:

  • C++11 [n3690] (final draft)
  • C++17 [n4659] (final draft)
  • C++20 [n4835] (current draft)

C++11 3.10 Lvalues and rvalues

... A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [ Example: The result of calling a function whose return type is not a reference is a prvalue. The value of a literal such as 12, 7.3e5, or true is also a prvalue. — end example ]

C++17 3.10 Lvalues and rvalues

... A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.

C++20 7.2.1 Value categories*

... A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of an operand of an operator, as specified by the context in which it appears, or an expression that has type cv void.

I would understand the wording changes, and some adjustments are made, but for me the entire definition changes. Can someone help me to understand this? For instance, why was the sentence removed that a prvalue is an rvalue that is not an xvalue? Or why did the helpful example got removed?

like image 266
Daniel Stephens Avatar asked Oct 31 '19 03:10

Daniel Stephens


1 Answers

The original prvalue definition was just a label: we set aside certain rvalues (namely, those that are not xvalues) and give them a name. It’s impossible to take their address except via unusual this usage (more or less because they’re temporaries), so certain liberties can be taken with their creation and propagation without breaking anything. (See also a recent discussion of them not “having identity”.)

The new definition explicitly says that a prvalue is an initialization “waiting to happen”: once a target object is identified for it, it is what gets initialized. (It’s important to note that the initialization still happens when the prvalue is constructed, just not where it is.) This goes by the name of “mandatory copy elision” based on the equivalent optimization that was already common.

As for the example, the new value category definitions were seen as being so much simpler that fewer examples were needed. There still is one for xvalues (which are the subtlest category).

like image 71
Davis Herring Avatar answered Oct 23 '22 06:10

Davis Herring