Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:16385 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 95068 invoked by uid 1010); 5 Jun 2005 18:50:28 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 95053 invoked from network); 5 Jun 2005 18:50:28 -0000 Received: from unknown (HELO php.net) (127.0.0.1) by localhost with SMTP; 5 Jun 2005 18:50:28 -0000 X-Host-Fingerprint: 82.165.35.142 thinkforge.org Linux 2.4/2.6 Received: from ([82.165.35.142:29253] helo=mail.mayflowersystem.com) by pb1.pair.com (ecelerity 1.2 r(5656M)) with SMTP id 43/11-56751-27943A24 for ; Sun, 05 Jun 2005 14:50:26 -0400 Received: (qmail 19475 invoked by uid 60010); 5 Jun 2005 18:50:19 -0000 Received: from 82.135.77.174 by mail (envelope-from , uid 89) with qmail-scanner-1.24 (uvscan: v4.3.20/v4362. spamassassin: 2.63. Clear:RC:1(82.135.77.174):. Processed in 0.554168 secs); 05 Jun 2005 18:50:19 -0000 Received: from unknown (HELO ?192.168.1.102?) (schlueter@mayflower.de@82.135.77.174) by 0 with (RC4-MD5 encrypted) SMTP; 5 Jun 2005 18:50:18 -0000 To: internals@lists.php.net Date: Sun, 5 Jun 2005 20:48:57 +0200 User-Agent: KMail/1.8 MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_ak0oCL+PpHv3PDQ" Message-ID: <200506052048.58029.johannes@php.net> Subject: incrementing boolean values From: johannes@php.net (Johannes Schlueter) --Boundary-00=_ak0oCL+PpHv3PDQ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi, PHP is a weak-typed language which casts in the background as required - at= =20 least most of the time. I recently found an exception which bugged me: $a =3D false; $a++; Here $a isn't casted to int or "incremented" to true but the incrementing h= as=20 no effect. By checking zend_operators.c I saw that booleans had no explicit= =20 incrementing rule but uses just the default in the relevant switch. Looking a bit deeper it got quite interesting: NULL++ gives as result the=20 integer one. This is fine for incrementing undefined variables but imho=20 inconsistent with the behavior of false. NULL-- evaluates to NULL similar t= o=20 false but different from NULL++. All this makes using PHP harder than needed. At least I spent quite some ti= me=20 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= =20 casting bools and NULL to long. Yes, it would be a BC break but I don't thi= nk=20 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:=20 http://www.schlueters.de/zend_incdec_with_bool.diff =2D-=20 Johannes Schl=FCter Mayflower GmbH / ThinkPHP http://thinkphp.de http://blog.thinkphp.de --Boundary-00=_ak0oCL+PpHv3PDQ Content-Type: text/plain; charset="iso-8859-1"; name="zend_incdec_with_bool.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="zend_incdec_with_bool.diff" 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); --Boundary-00=_ak0oCL+PpHv3PDQ--