rfc:increment_decrement_fixes

This is an old revision of the document!


PHP RFC: Increment/Decrement Fixes

Introduction

The increment and decrement operators (++$a, $a++, --$a, $a--) mostly behave the same as adding 1 to the variable. However, because they are implemented separately, there are a handful of anomalies regarding non-integer values, which do are not incremented consistently with an integer cast.

Intuitively, the ++ and -- operators are equivalent to “add 1 to variable” and “subtract 1 from variable”, respectively. As such, it would be expected that $a=$a+1, $a+=1, and ++$a would end up with the same value in $a; and likewise, $a=$a-1, $a-=1, and --$a.

This is currently not the case, as the table below shows:

Initial Value $a = $a + 1 $a += 1 ++$a, $a++ $a = $a - 1 $a -= 1 --$a, $a--
0 1 1 1 -1 -1 -1
null 1 1 1 -1 -1 null
true 2 2 true 0 0 true
false 1 1 false -1 -1 false
array Error Error silent Error Error silent
object 2 (+ Notice) 2 (+ Notice) unchanged 0 (+ Notice) 0 (+ Notice) unchanged
resource#5 6 6 resource#5 4 4 resource #5

The reason this is possible is because ++ and -- are implemented separately for each type via a switch statement in the engine, rather than by coercing to integer. The default case in this switch statement is to silently leave the value unchanged.

Proposal 1: Decrementing Null

The behaviour of null with ++ is consistent with it being coerced to int(0); however, with -- the null remains unchanged.

This behaviour has been raised as a bug at least three times (#20548, #25674, #41690). All three are closed, and it is documented in the manual, but there is no evidence that it is intentional behaviour rather than an entrenched bug retained for compatibility.

Discrepancies in behaviour of null are particularly problematic, since undefined variables, array items, and object properties are widely treated as having a value of null.

This RFC proposes to change the behaviour, so that $a=null; $a--; or $a=null; --$a; will result in $a holding -1. This brings it into line with all other mathematical operations, include $a++, which treat null as equivalent to 0.

Proposal 2: Incrementing and Decrementing Booleans

The behaviour of booleans with most mathematical operations is to treat false as 0 and true as 1. However, the ++ and -- operators do not currently have an implementation for booleans, so they remain unchanged. The current behaviour is therefore this:

Initial Value $a = $a + 1 $a += 1 ++$a, $a++ $a = $a - 1 $a -= 1 --$a, $a--
true 2 2 true 0 0 true
false 1 1 false -1 -1 false

This RFC proposes to change the behaviour so that it is in line with other mathematical contexts, giving this:

Initial Value $a = $a + 1 $a += 1 ++$a, $a++ $a = $a - 1 $a -= 1 --$a, $a--
true 2 2 2 0 0 0
false 1 1 1 -1 -1 -1

Backward Incompatible Changes

The proposed changes to null and boolean handling are not backwards compatible. The current behaviour is not particularly useful, so it is unlikely that code is deliberately relying on it.

Proposed PHP Version(s)

8.0

RFC Impact

Open Issues

objects, arrays, resources...

Unaffected PHP Functionality

* Undefined variables, array items, and object properties are currently treated as null for most purposes, including the ++ and -- operators. Changing this behaviour is out of scope of this RFC, and the behaviour of variables explicitly set to null would still need to be defined. * Similarly, most mathematical contexts will coerce null and false to 0, and true to 1; this RFC does not seek to change any cases where that logic is followed. Changes to that general principle might render this RFC obsolete, but might require a period of deprecation, so consistency of the current approach may still be valuable. * Strings overload the ++ and -- operators with complex behaviour not discussed here. Improving this deserves its own discussion, so has been left out of this RFC.

Proposed Voting Choices

* Should decrementing null result in -1? (Yes / No) * Should incrementing and decrementing booleans act the same as addition and subtraction? (Yes / No)

Patches and Tests

TODO

Implementation

TODO

References

Rejected Features

TODO

rfc/increment_decrement_fixes.1583084492.txt.gz · Last modified: 2020/03/01 17:41 by imsop