4

From the Working Draft, Standard for Programming Language C++, [basic.lval/5]:

The result of a glvalue is the entity denoted by the expression. The result of a prvalue is the value that the expression stores into its context; a prvalue that has type cv void has no result. A prvalue whose result is the value V is sometimes said to have or name the value V. The result object of a prvalue is the object initialized by the prvalue; a non-discarded prvalue that is used to compute the value of an operand of a built-in operator or a prvalue that has type cv void has no result object.

[Note 4: Except when the prvalue is the operand of a decltype-specifier, a prvalue of class or array type always has a result object. For a discarded prvalue that has type other than cv void, a temporary object is materialized; see [expr.context]. — end note]

What is the difference between initializing an object and computing a value?

Some examples of each would be appreciated.

Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
  • 1
    `int i = 1;` — `1` initializes an object, has result object. `i = 1;` — `1` has no result object, computes the value of built-in `=` operator; `1 + 1;` — same. – Language Lawyer Sep 07 '21 at 19:07
  • @LanguageLawyer Thanks. Same examples with a class type `struct S{ int i; };`: would `S{1}` initialize an *object* in `S s = S{1};` and compute a *value* in `s = S{1};`? – Géry Ogam Sep 07 '21 at 21:07
  • 1
    Both cases initialize an object, since the second one is an invocation of `S::operator=` – Language Lawyer Sep 07 '21 at 22:02
  • @LanguageLawyer Alright, but for the second `int` example, aren’t we invoking the built-in function `int operator=(int);` as well, thereby initializing its parameter, i.e. initializing an object? – Géry Ogam Sep 07 '21 at 22:56
  • 1
    _«invoking the built-in function `int operator=(int);`»_ is not a thing. `i = 1` is evaluated as described in https://timsong-cpp.github.io/cppwp/n4868/expr.ass#2 – Language Lawyer Sep 07 '21 at 23:04
  • @LanguageLawyer Okay, three questions come to mind: 1. Does a result object mean putting a value in a *new* storage location? 2. Does a prvalue expression which is not the operand of a *built-in* operator and not of type *cv* `void` always have a result object? 3. Can a glvalue expression have a result object? – Géry Ogam Sep 08 '21 at 06:39
  • 1. IDK how to determine if storage location is *new*. 2. The note says that class and array prvalues almost always has result object. 3. No – Language Lawyer Sep 08 '21 at 07:03
  • @LanguageLawyer 1. I am trying to understand the core difference between a result and a result object, so after seeing your examples my intuition was that it was about the allocation of a new storage location, since in `i = 1;` we are merely replacing the value at the *existing* storage location `&i` with the value `1`, while in `s = S{1};` prior to that replacement we are allocating a *new* storage location for the parameter of `S::operator=`. 2. What about the other C++ types? 3. So in `s = s;` the `s` on the right has no result object though it initializes the parameter of `S::operator=`? – Géry Ogam Sep 08 '21 at 09:01
  • @LanguageLawyer Also about point 3, your statement that glvalues cannot have result objects seems to conflict with [\[conv.lval/3.2\]](https://timsong-cpp.github.io/cppwp/conv.lval#3.2): ‘Otherwise, if `T` has a class type, the conversion copy-initializes the result object from the glvalue.’ – Géry Ogam Sep 08 '21 at 14:49
  • 1
    It is the result object of a prvalue produced by the lvalue-to-rvalue conversion. – Language Lawyer Sep 08 '21 at 15:05
  • @LanguageLawyer I see. As I expected, what the C++ standard calls an *object* is a *stored* value, cf. [\[intro.object/1\]](https://timsong-cpp.github.io/cppwp/basic#intro.object-1): ‘An object occupies a region of storage in its period of construction ([class.cdtor]), throughout its lifetime, and in its period of destruction ([class.cdtor]).’ So I think the main difference about initializing an object and computing a value can be described by this equation: initializing an object = computing a value + storing that value. Would you like to post an answer with your examples and this equation? – Géry Ogam Sep 08 '21 at 17:45
  • _As I expected, what the C++ standard calls an object is a stored value_ I wouldn't try to define "object" through "value", since the former concept looks simpler than the later to me – Language Lawyer Sep 09 '21 at 08:16
  • @LanguageLawyer How would you define an object? – Géry Ogam Sep 09 '21 at 09:04
  • https://timsong-cpp.github.io/cppwp/basic#def:object – Language Lawyer Sep 09 '21 at 09:12
  • @LanguageLawyer It specifies: ‘An object occupies a region of storage in its period of construction ([class.cdtor]), throughout its lifetime, and in its period of destruction ([class.cdtor]).’ So an object is something stored. [\[basic.indet-1\]](https://timsong-cpp.github.io/cppwp/basic#indet-1) specifies: ‘When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]).’ So it is a stored *value*. – Géry Ogam Sep 09 '21 at 09:39
  • @LanguageLawyer I am not sure anymore that your example `i = 1;` of a prvalue that does not have a result object is correct. Because it agrees with [\[basic.lval/5\]](https://timsong-cpp.github.io/cppwp/n4868/basic.lval#5) (bold emphasis mine): ‘The *result object* of a prvalue is the object initialized by the prvalue; **a non-discarded prvalue that is used to compute the value of an operand of a built-in operator or a prvalue that has type *cv* `void` has no result object.**’ But it disagrees with [\[basic.life/8\]](https://timsong-cpp.github.io/cppwp/basic#life-8) (bold emphasis mine): – Géry Ogam Sep 09 '21 at 12:22
  • … ‘If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, **a new object is created at the storage location which the original object occupied,** a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if the original object is transparently replaceable (see below) by the new object.’ Created object = result object. – Géry Ogam Sep 09 '21 at 12:28

0 Answers0