incrementing boolean values
| From: | Johannes Schlueter | Date: | Sun, 05 Jun 2005 18:48:57 +0000 |
| Subject: | incrementing boolean values | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-16385@lists.php.net to get a copy of this message | ||
Hi,
PHP is a weak-typed language which casts in the background as required - at
least most of the time. I recently found an exception which bugged me:
$a = false;
$a++;
Here $a isn't casted to int or "incremented" to true but the incrementing has
no effect. By checking zend_operators.c I saw that booleans had no explicit
incrementing rule but uses just the default in the relevant switch.
Looking a bit deeper it got quite interesting: NULL++ gives as result the
integer one. This is fine for incrementing undefined variables but imho
inconsistent with the behavior of false. NULL-- evaluates to NULL similar to
false but different from NULL++.
All this makes using PHP harder than needed. At least I spent quite some time
finding that my variable was set to false instead of 0 (or NULL).
I wrote the attached patch which allows in-/decrementing of simple types by
casting bools and NULL to long. Yes, it would be a BC break but I don't think
someone relies on false++ being false and it would make life simpler.
Comments?
johannes
P.S. If the patch doesn't come through: It's available via web, too:
http://www.schlueters.de/zend_incdec_with_bool.diff
--
Johannes Schlüter Mayflower GmbH / ThinkPHP
http://thinkphp.de http://blog.thinkphp.de
Index: Zend/zend_operators.c =================================================================== RCS file: /repository/ZendEngine2/zend_operators.c,v retrieving revision 1.205 diff -u -p -r1.205 zend_operators.c --- Zend/zend_operators.c 8 Apr 2005 14:33:00 -0000 1.205 +++ Zend/zend_operators.c 31 May 2005 10:40:11 -0000 @@ -1679,6 +1679,10 @@ ZEND_API int increment_function(zval *op case IS_DOUBLE: op1->value.dval = op1->value.dval + 1; break; + case IS_BOOL: + op1->value.lval++; + op1->type = IS_LONG; + break; case IS_NULL: op1->value.lval = 1; op1->type = IS_LONG; @@ -1736,6 +1740,14 @@ ZEND_API int decrement_function(zval *op case IS_DOUBLE: op1->value.dval = op1->value.dval - 1; break; + case IS_BOOL: + op1->value.lval--; + op1->type = IS_LONG; + break; + case IS_NULL: + op1->value.lval = -1; + op1->type = IS_LONG; + break; case IS_STRING: /* Like perl we only support string increment */ if (op1->value.str.len == 0) { /* consider as 0 */ STR_FREE(op1->value.str.val);
Index: Zend/zend_operators.c =================================================================== RCS file: /repository/ZendEngine2/zend_operators.c,v retrieving revision 1.205 diff -u -p -r1.205 zend_operators.c --- Zend/zend_operators.c 8 Apr 2005 14:33:00 -0000 1.205 +++ Zend/zend_operators.c 31 May 2005 10:40:11 -0000 @@ -1679,6 +1679,10 @@ ZEND_API int increment_function(zval *op case IS_DOUBLE: op1->value.dval = op1->value.dval + 1; break; + case IS_BOOL: + op1->value.lval++; + op1->type = IS_LONG; + break; case IS_NULL: op1->value.lval = 1; op1->type = IS_LONG; @@ -1736,6 +1740,14 @@ ZEND_API int decrement_function(zval *op case IS_DOUBLE: op1->value.dval = op1->value.dval - 1; break; + case IS_BOOL: + op1->value.lval--; + op1->type = IS_LONG; + break; + case IS_NULL: + op1->value.lval = -1; + op1->type = IS_LONG; + break; case IS_STRING: /* Like perl we only support string increment */ if (op1->value.str.len == 0) { /* consider as 0 */ STR_FREE(op1->value.str.val);