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);
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php