12

The C++11 and C++14 standard (and working draft, respectively) say in §3.10.1:

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 ]

and

An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object.

Which leads me to the question: How can an expression be "a value not associated with an object"?

I was under the impression, that it is the purpose of expressions to return objects or void (which I do not expect to be a value either).

Is there some simple and common example for such expressions?

Edit 1

To further complicate things, consider the following:

int const& x = 3;
int&& y = 4;

In context of §8.3.2.5, which contains the most interesting snippet:

[...] A reference shall be initialized to refer to a valid object or function [...]

Which is reinforced by §8.5.3.1:

A variable declared to be a T& or T&&, that is, “reference to type T” (8.3.2), shall be initialized by an object, or function, of type T or by an object that can be converted into a T. [...]

danielschemmel
  • 10,885
  • 1
  • 36
  • 58
  • 6
    42; ;;;;;;;;;;;;;;;; – Stephan Dollberg Sep 04 '14 at 20:56
  • Non-lvalue expressions yield *values*, not objects. – Keith Thompson Sep 04 '14 at 21:02
  • 2
    @KeithThompson So, a prvalue expression that yields a temporary object, does not yield an object? *confused* – danielschemmel Sep 04 '14 at 21:35
  • 1
    I'm not entirely sure; I know C better than C++, and C just has lvalues and non-lvalues. In any case, the value of the expression `42` is a prvalue that's not associated with an object; evaluating `42` doesn't create an `int` object. – Keith Thompson Sep 04 '14 at 21:41
  • I immediately think that `nullptr`, `true`, `this`, etc might be values without an object, but I am uncertain. – Mooing Duck Sep 04 '14 at 21:42
  • @KeithThompson I have added some complications with references to the question that arise when `42` does not create a temporary object. – danielschemmel Sep 04 '14 at 22:20
  • @gha.st The reference parts work via the last bullet point of [dcl.init.ref]/5: "Otherwise, a temporary of type “*cv1* `T1`” is created [...]" That is, `int const& x = 3;` creates a temporary (object) initialized with `3` and binds *that object* to the reference. Edit: Ah, I just saw you discussed that already in the comments to Anton's answer. – dyp Sep 04 '14 at 23:28

3 Answers3

5

[intro.object]:

The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is a region of storage. [ Note: A function is not an object, regardless of whether or not it occupies storage in the way that objects do. —end note ] An object is created by a definition (3.1), by a new-expression (5.3.4) or by the implementation (12.2) when needed.

So "a value not associated with an object" is something created not by definition or with new-expression, which also means that it doesn't have corresponding region of storage, like for example a literal.

Edit: Except string literals (see comments)

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • String literals are lvalues (§5.1.1.1) - would this definition not imply that they are not objects (conflicting with the definition of lvalue) and do not have a corresponding region of storage? – danielschemmel Sep 04 '14 at 21:33
  • @gha.st: String literals are lvalues. I believe Anton was referring to integral and floating point literals. – Mooing Duck Sep 04 '14 at 21:43
  • @MooingDuck String literals are not created by a definition, nor a new-expression, which leads me to suspect that there may be a bit more to it, than meets the (well, at least my) eye – danielschemmel Sep 04 '14 at 21:50
  • @gha.st I think there might be some gap in the standard here. If string literal is an lvalue it must be an object, and of course there is region of storage associated with it, because you can assign `const char*` pointer to it. – Anton Savin Sep 04 '14 at 21:59
  • @AntonSavin: I'm pretty sure you can't assign a `const char*` to a string literal... – Mooing Duck Sep 04 '14 at 22:08
  • @MooingDuck `const char* p = "hello world";` – Anton Savin Sep 04 '14 at 22:10
  • `int&& x = 3;` should be impossible if `3` does not cause an object to be created (see question edit 1). – danielschemmel Sep 04 '14 at 22:21
  • 1
    @gha.st `3` does not cause an object to be created, but reference biding does – Cubbi Sep 04 '14 at 22:23
  • @Cubbi I can only see that to be the case for class types. Can you elaborate on this for the non-class types we are looking at here? – danielschemmel Sep 04 '14 at 22:31
  • @gha.st It's described in `8.5.3/5` near the end. And `12.2` references `8.5` as possible source of temporaries. – Anton Savin Sep 04 '14 at 22:47
4

Examples for such values are all non-array, non-class non-temporary prvalues (a temporary prvalue corresponds to a temporary object). Examples include 2.0 and 1. Counterexamples include "hello" (which is an array), std::string("haha") (which is a class object) or the float prvalue temporary initialized from 2 that is bound to the reference in (const float&){2} (the reference itself is an lvalue!). I think that this simple rule covers the rules accurately.

A C++ Standard's footnote on the lvalue to rvalue conversion says (a little bit outdated, because it was not amended to mention array types)

In C ++ class prvalues can have cv-qualified types (because they are objects). This differs from ISO C, in which non-lvalues never have cv-qualified types.

So the deeper reason that decltype((const int)0) still is type int is that it does not refer to an object. So because there is no object, there is nothing to make const, and consequently the expression will never be const either.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
1

This quote is not as precisely worded as it could be:

An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object.

An rvalue is an expression , so it cannot be an object (temporary or otherwise). The intent of the section of this quote talking about temporary objects is to say that value resulting from evaluating the rvalue is a temporary object, and so on.

This is a common shortcut, e.g. with int x; we would casually say "x is in int" , when in fact x is an identifier; and the expression x has type int and designates an int.

Anyway, it divides possible rvalues up into three categories:

  • xvalue
  • temporary object
  • value not associated with an object

The definition of temporary object includes being an object of class type, so it seems to me that "value not associated with an object" should be any non-xvalue of non-class type. For example 1 + 1.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • *"It means that the value resulting from evaluating the rvalue is a temporary object"* I do not think this is necessarily the case. Integer literals are rvalue-expressions but there's no object (i.e. region of storage) associated with them. – dyp Sep 04 '14 at 23:25
  • @dyp Then it would not be a temporary object, according to the definition of 12.2 – M.M Sep 04 '14 at 23:30
  • Sorry, but I don't quite understand what you're referring to with "then" and "it". – dyp Sep 04 '14 at 23:33
  • In my comment? "Then" means "as a consequence of what you said", and "it" means the integer literal you are talking about. – M.M Sep 04 '14 at 23:36
  • Ah, thanks. -- But according to 12.2, there are no temporary objects of type `int`. So "evaluating an rvalue", e.g. as in `42 + 3`, does *not* create an object. See also http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#943 (especially the last sentence). (Also, a value is not an object.) – dyp Sep 04 '14 at 23:45
  • 1
    @dyp I think we are in agreement. My suggestion is that rvalues (which are not xvalues) which are of class type are *temporary object* and which are not of class type are *value not associated with an object*. – M.M Sep 04 '14 at 23:53