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