I've been reading quite many on the Internet and it seems that many people mentioned the following rules (but i couldn't find it in the standard),
The addition operator + (and all other binary operators) requires both operands to be rvalue, and the result is rvalue. And so on..
I checked the C++ standard, and it clearly states that (clause 3.10/2),
Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted to a prvalue
(clause 5/9),
Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue (4.1), array-to-pointer (4.2), or function-to-pointer (4.3) standard conversions are applied to convert the expression to a prvalue.
It uses a term the operand "expects" a prvalue. However, when I look into addition operator, multiplication operator etc, it only mentions that, the result is a prvalue, but it doesn't say anything on what the operands are "expected" to be.
Whether does the binary operator really expects the operands to be prvalue makes a difference in the following case,
int b = 2;
int a = b + 1;
If b is expected to be a prvalue, there will be a lvalue-to-rvalue conversion here, and then it will perform prvalue + prvalue and return a prvalue, and the result prvalue is assigned to an lvalue a.
However, if b is not required to be a prvalue, it would be lvalue + prvalue and the result is a prvalue.
I really want to know where does the standard explicitly or implicitly mentions that the rules for different operators? I check all the operators section and only a few operators that the standards explicitly mentions whether the operands and results shall be lvalue or rvalue. For most operators, the standard only mentions the result but not the operand requirement.
Thanks.
Btw, I found in Standard 5.19 regarding constant expression may very very "implicitly" imply that the binary operator require lvalue-to-rvalue conversion on operands. For more details, please refer to my previous question,
mixing use of constexpr and const?
A conditional-expression is a constant expression unless it involves one of the following as a potentially evaluated subexpression (3.2).
...
— an lvalue-to-rvalue conversion (4.1) unless it is applied to
———— a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression
Thanks for reading.
So, this is generally one of those inferred and ill-specified parts of the standard; However, in 3.10
[ Note: some built-in operators expect lvalue operands. [ Example: built-in assignment operators all expect their left-hand operands to be lvalues. — end example ] Other built-in operators yield rvalues, and some expect them. [ Example: the unary and binary + operators expect rvalue arguments and yield rvalue results. — end example ] The discussion of each built-in operator in clause 5 indicates whether it expects lvalue operands and whether it yields an lvalue. — end note ]
Notice the poorly specified language "in clause 5 indicates whether it expects lvalue operands and whether it yields an lvalue".
Examination of Chapter 5 indicates that every case where an expression needs or returns an lvalue is enumerated, however very few cases dealing specifically with rvalues are enumerated, I think it's then assumed that the rest is assumed to be rvalues.
I also suspect it's poorly specified because from the perspective of the standard, it's not particularly important if the conversion is done implicitly or explicitly by the operator, regardless, the behavior should be the consistent and well-behaved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With