cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2855 [expr.post.incr] has no integral promotion, [expr.pre.incr] has #479

Closed leni536 closed 2 months ago

leni536 commented 6 months ago

Full name of submitter: Lénárd Szolnoki

Reference (section label): [expr.post.incr]

The value of the operand object is modified by adding 1 to it.

Issue description

consider:

int8_t x = 127;
x++;

This has undefined behavior: the value is increased by 1 but the resulting value is not representable in int8_t [expr.pre].

In comparison [expr.pre.incr] in addition has:

The expression ++x is equivalent to x+=1.

Which in turn is equivalent to x = x + 1, except that x is evaluated only once. This implies that integral promotion rules are considered.

Because of this the following is defined:

int8_t x = 127;
++x;

where ++x is equivalent to x = (int)x + 1.

Implementations

GCC, clang and MSVC accept both examples above in constant expressions. They otherwise detect overflowing increments when no promotion is involved.

Suggested resolution

Spell out that the side effects of post-increment are equivalent to the side-effects of pre-increment, with the implied integral promotions.

t3nsor commented 6 months ago

Possible resolution:

Edit [expr.post.incr]:

The value of a postfix ++ expression is the value of its operand.
[Note 1: The value obtained is a copy of the original value. — end note]
~The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type other than cv bool, or a pointer to a complete object type. An operand with volatile-qualified type is deprecated; see [depr.volatile.type].~ The value of the operand object is modified ([defns.access]) ~by adding 1 to it~ as if it were the operand of the prefix ++ operator. The value computation of the ++ expression is sequenced before the modification of the operand object. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation.
[Note 2: Therefore, a function call cannot intervene between the lvalue-to-rvalue conversion and the side effect associated with any single postfix ++ operator. — end note]
The result is a prvalue. The type of the result is the cv-unqualified version of the type of the operand. ~If the operand is a bit-field that cannot represent the incremented value, the resulting value of the bit-field is implementation-defined. See also [expr.add] and [expr.ass].~

The operand of postfix -- is decremented analogously to the postfix ++ operator.
[Note 3: For prefix increment and decrement, see [expr.pre.incr]. — end note]

Edit [expr.pre.incr]:

The operand of prefix ++ or -- ~is modified ([defns.access]) by adding 1. The operand shall be a modifiable lvalue. The type of the operand~ shall not be ~an arithmetic type other than~ of type cv bool~, or a pointer to a completely-defined object type~. An operand with volatile-qualified type is deprecated; see [depr.volatile.type]. ~The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field.~ The expression ++x is otherwise equivalent to x+=1 and the expression --x is otherwise equivalent to x-=1.
~[Note 1: See the discussions of addition and assignment operators for information on conversions. — end note]~

~The operand of prefix -- is modified ([defns.access]) by subtracting 1. The requirements on the operand of prefix -- and the properties of its result are otherwise the same as those of prefix ++.~
[Note ~2~ 1: For postfix increment and decrement, see [expr.post.incr]. — end note]

jensmaurer commented 5 months ago

CWG2855

pinskia commented 4 months ago

Hmm, this seems to make an C and C++ (defined) behavior different with represent to post increment. I would have hoped post increment still be well defined here too.

jensmaurer commented 4 months ago

@pinskia, could you please elaborate? The proposal is to have prefix and postfix increment/decrement have the same (well-defined) behavior by applying integral promotions in both cases.

pinskia commented 4 months ago

@pinskia, could you please elaborate? The proposal is to have prefix and postfix increment/decrement have the same (well-defined) behavior by applying integral promotions in both cases.

Oh I read as the opposite for some reason, thanks for the carification there.