danielschemmel
danielschemmel

Reputation: 11126

What is "a value not associated with an object"?

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. [...]

Upvotes: 12

Views: 546

Answers (3)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507105

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.

Upvotes: 4

M.M
M.M

Reputation: 141628

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.

Upvotes: 1

Anton Savin
Anton Savin

Reputation: 41321

[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)

Upvotes: 5

Related Questions