18
votes

PREMISE:

The C++11 Standard classifies expressions into three disjoint value categories: lvalues, xvalues, and prvalues (§ 3.10/1). An explanation of what value categories are is available for instance here.

I am struggling to figure out what are the requirements of the different operators on the value category of their operands. Paragraph 3.10/1 specifies:

[...] Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue. This property of an expression is called its value category. [ Note: The discussion of each built-in operator in Clause 5 indicates the category of the value it yields and the value categories of the operands it expects. For example, the built-in assignment operators expect that the left operand is an lvalue and that the right operand is a prvalue and yield an lvalue as the result. User-defined operators are functions, and the categories of values they expect and yield are determined by their parameter and return types. —end note ]

In spite of what the note above claims, Clause 5 is not always very clear about the value category of operators' operands. This is, for instance, all that is said about the value category of the operands of the assignment operator (Paragraph 5.17/1):

The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single compound assignment operator. —end note ]

How about the right operands?

The words "rvalue" and "lvalue" no more occur in the whole Section 5.17. While the note in Paragraph 3.10/1 makes it explicit that the built-in assignment operators expect a prvalue as a right operand, this is not explicitly mentioned in Section 5.17. Even the final note of 5.17/1, which mentions lvalue-to-rvalue conversions, seems to imply that rvalues are expected somehow (what's the need for a conversion otherwise?), but notes are non-normative after all.

Sections concerning other operators, including multiplicative and additive operators, are generally silent on the value category of their operands. I couldn't find any "default statement" in the Standard stating that, when not specified otherwise, the operands of built-in operators are rvalues. Hence, the question.

QUESTION:

  1. What is the value category of the right operand of the assignment operator; and, more generally
  2. How to figure out the value category of an operator's operand when this is is not specified? Is it unconstrained (meaning that any value category is accepted)? If so, why should lvalue-to-rvalue conversions ever apply in an assignment expression?

References to the C++11 Standard are highly appreciated.

1
The value category of the Right hand side is whatever the function parameter expects (I think && are prvalues, & are lvalues, const& are anything, and values are anything). For all primitive types, we can infer the signature is T& operator=(const T&rhs), but I don't think it is explicitly stated anywhere.Mooing Duck
Heh, the note says that "Clause 5 indicates" and not "Clause 5 defines" :) The indication for assignment is 5.17p2 "In simple assignment (=), the value of the expression replaces that of the object referred to by the left operand."Johannes Schaub - litb
@JohannesSchaub-litb: Do you know what's the intended specification? Provided it's ill-defined, are we meant to assume that right operands of built-in operators are rvalues when unspecified?Andy Prowl
@MooingDuck: Why so? For primitive types, it could equally well be T& operator=(T) I believe. No?Andy Prowl
@AndyProwl unfortunately, I don't think there is anything conclusive to say. I think the spec is ill-specified and leaves out the promised "discussion of each built-in operator" :)Johannes Schaub - litb

1 Answers

7
votes

Yes, it's ill-specified and has been covered before. Basically, every time an lvalue expression is required is enumerated, so we assume that every other operand must be a prvalue expression.

So to answer your questions:

  1. A prvalue.
  2. If it's not specified, it's a prvalue.

The note that is quoted in the linked answer seems to have changed a few times. The quote from §3.10 of the C++11 standard is as follows (and at the current time is identical in the latest draft):

[ Note: The discussion of each built-in operator in Clause 5 indicates the category of the value it yields and the value categories of the operands it expects. For example, the built-in assignment operators expect that the left operand is an lvalue and that the right operand is a prvalue and yield an lvalue as the result. User-defined operators are functions, and the categories of values they expect and yield are determined by their parameter and return types. — end note ]

Here it even says explicitly that the assignment operators expect the right operand to be a prvalue. Of course, this is a note and is therefore non-normative.