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

Reply via email to