This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-10-26


1642. Missing requirements for prvalue operands

Section: 7.6  [expr.compound]     Status: DRWP     Submitter: Joseph Mansfield     Date: 2013-03-15

[Accepted as a DR at the June, 2023 meeting.]

Although the note in 7.2.1 [basic.lval] paragraph 1 states that

The discussion of each built-in operator in Clause 7 [expr] indicates the category of the value it yields and the value categories of the operands it expects

in fact, many of the operators that take prvalue operands do not make that requirement explicit. Possible approaches to address this failure could be a blanket statement that an operand whose value category is not stated is assumed to be a prvalue; adding prvalue requirements to each operand description for which it is missing; or changing the description of the usual arithmetic conversions to state that they imply the lvalue-to-rvalue conversion, which would cover the majority of the omissions.

(See also issue 1685, which deals with an inaccurately-specified value category.)

Proposed resolution (approved by CWG 2023-04-28):

  1. Change in 7.2.1 [basic.lval] paragraph 6 as follows:

    Whenever a glvalue appears as an operand of an operator that expects requires a prvalue for that operand, the lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer (7.3.3 [conv.array]), or function-to-pointer (7.3.4 [conv.func]) standard conversions are applied to convert the expression to a prvalue. ...
  2. Change in 7.3.1 [conv.general] paragraph 1 as follows:

    ... A standard conversion sequence will be applied to an expression if necessary to convert it to an expression having a required destination type and value category. ...
  3. Add to the bulleted list in 7.4 [expr.arith.conv] paragraph 1 as follows:

    ... This pattern is called the usual arithmetic conversions, which are defined as follows:
    • The lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is applied to each operand and the resulting prvalues are used in place of the original operands for the remainder of this section.
    • If either operand is of scoped enumeration type (9.7.1 [dcl.enum]), no conversions are performed; if the other operand does not have the same type, the expression is ill-formed.
    • ...
  4. Change in 7.6.1.3 [expr.call] paragraph 1 as follows:

    ... For a call to a non-member function or to a static member function, the postfix expression shall be either be an lvalue that refers to a function (in which case the function-to-pointer standard conversion (7.3.4 [conv.func]) is suppressed on the postfix expression), or have a prvalue of function pointer type.
  5. Change in 7.6.2.2 [expr.unary.op] paragraph 7 as follows:

    The operand of the unary + operator shall have be a prvalue of arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument. Integral promotion is performed on integral or enumeration operands. ...
  6. Change in 7.6.2.2 [expr.unary.op] paragraph 8 as follows:

    The operand of the unary - operator shall have be a prvalue of arithmetic or unscoped enumeration type and the result is the negative of its operand. Integral promotion is performed on integral or enumeration operands. ...
  7. Change in 7.6.2.2 [expr.unary.op] paragraph 10 as follows:

    The operand of the ~ operator shall have be a prvalue of integral or unscoped enumeration type. Integral promotions are performed. ...
  8. Change in 7.6.2.9 [expr.delete] paragraph 1 as follows:

    ... The operand shall be of pointer to object type or of class type. If the operand is of class type, the operand it is contextually implicitly converted (7.3 [conv]) to a pointer to object type. [ Footnote: ... ] Otherwise, it shall be a prvalue of pointer to object type. The delete-expression has type void.
  9. Change in 7.6.4 [expr.mptr.oper] paragraph 2 and 3 as follows:

    The binary operator .* binds its second operand, which shall be a prvalue of type “pointer to member of T” to its first operand, which shall be ...

    The binary operator ->* binds its second operand, which shall be a prvalue of type “pointer to member of T” to its first operand, which shall be ...

  10. Change in 7.6.6 [expr.add] paragraph 1 as follows:

    The additive operators + and - group left-to-right. The Each operand shall be a prvalue. If both operands have arithmetic or unscoped enumeration type, the usual arithmetic conversions (7.4 [expr.arith.conv]) are performed for operands of arithmetic or enumeration type. Otherwise, if one operand has arithmetic or unscoped enumeration type, integral promotion is applied (7.3.7 [conv.prom]) to that operand. A converted or promoted operand is used in place of the corresponding original operand for the remainder of this section. ... For addition, either both operands shall have arithmetic or unscoped enumeration type, or one operand shall be a pointer to a completely-defined object type and the other shall have integral or unscoped enumeration type.
  11. Change in 7.6.6 [expr.add] paragraph 2 as follows:

    For subtraction, one of the following shall hold:
    • both operands have arithmetic or unscoped enumeration type; or
    • both operands are pointers to cv-qualified or cv-unqualified versions of the same completely-defined object type; or
    • the left operand is a pointer to a completely-defined object type and the right operand has integral or unscoped enumeration type.
  12. Change in 7.6.7 [expr.shift] paragraph 1 as follows:

    ... The operands shall be prvalues of integral or unscoped enumeration type and integral promotions are performed. ...
  13. Change in 9.4.1 [dcl.init.general] bullet 16.9 as follows:

    • ...
    • Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. A standard conversion sequence (7.3 [conv]) will be is used, if necessary, to convert the initializer expression to a prvalue of the cv-unqualified version of the destination type; no user-defined conversions are considered. ...
    • ...