Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:16601 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69523 invoked by uid 1010); 10 Jun 2005 16:46:13 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 69508 invoked from network); 10 Jun 2005 16:46:13 -0000 Received: from unknown (HELO xs4all.nl) (127.0.0.1) by localhost with SMTP; 10 Jun 2005 16:46:13 -0000 X-Host-Fingerprint: 194.109.24.21 smtp-vbr1.xs4all.nl FreeBSD 4.6-4.9 Received: from ([194.109.24.21:4446] helo=smtp-vbr1.xs4all.nl) by pb1.pair.com (ecelerity 1.2 r(5656M)) with SMTP id 5B/46-18818-5D3C9A24 for ; Fri, 10 Jun 2005 12:46:13 -0400 Received: from duron.xs4all.nl (a213-84-38-246.adsl.xs4all.nl [213.84.38.246]) (authenticated bits=0) by smtp-vbr1.xs4all.nl (8.13.3/8.13.3) with ESMTP id j5AGkAmt043942 for ; Fri, 10 Jun 2005 18:46:10 +0200 (CEST) (envelope-from ganswijk@xs4all.nl) Message-ID: <6.2.1.2.2.20050610091349.0aff2c00@localhost> X-Mailer: QUALCOMM Windows Eudora Version 6.2.1.2 Date: Fri, 10 Jun 2005 10:01:10 +0200 To: internals@lists.php.net In-Reply-To: <1558647963.20050606083713@marcus-boerger.de> References: <200506052048.58029.johannes@php.net> <1558647963.20050606083713@marcus-boerger.de> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" X-Virus-Scanned: by XS4ALL Virus Scanner Subject: Re: [PHP-DEV] incrementing boolean values From: ganswijk@xs4all.nl (Jaap van Ganswijk) At 2005-06-06 08:37, Marcus Boerger wrote: >Sunday, June 5, 2005, 10:27:51 PM, you wrote: >> On Sun, 5 Jun 2005, Johannes Schlueter wrote: >>> PHP is a weak-typed language which casts in the background as required - at >>> least most of the time. Yes, but I think it doesn't always do it in an intuitive way and I would rather have errors or warnings instead. >>> 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. Yes, that is strange. I would like to plead for a real boolean type. The argument of an if or while statement for example has to be boolean (or convertable to boolean). In your case '$a=false;' should give $a the type and I don't think that integer arithmetic should be allowed on booleans, because it's confusing and unnecessary. Give an error or warning instead. >>> 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++. NULL comes from C I think and stands for an uninitialized pointer. There is no other way to empty a pointer except by using 'pointer=(*char)0;', using NULL is more clear. Instead of filling a variable with a null pointer one can unset() a variable in PHP. I have no problems with integers and strings being promoted to booleans, except for example that an empty string is considered to be false and even (in some versions?) a string containing '0' or even 'false' or even 'NULL'? I like to write: while (fgets($hf)) { } But this fails when an empty string is considered to be false. BTW. the behaviour also depends on the fact if "\r\n" is considered to be empty or not. I don't remember if it also happens in the case above or only in bigger expressions. >>> 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). My point too. Scripts in overly permissive and 'intelligent' languages like PHP tend to be hard to debug. C and Javascript were also made much more strict later. BTW. Wouldn't it be a good idea to split this mailing list in a list about the definition of the PHP language and the implementation and versions etc.? >>> 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? > >> I did this a year or so ago, and after discussing with Andi we decided >> not to promote types in this case. As I said above I agree with not auto-promoting booleans to other types. People should write '$i=(int)$b;' because this conversion is very unusual. >Not promoting types would mean adding false++, and true-- doesn't it? false is a constant and can't be increment. When you are in favor of incrementing booleans you should also be able to increment a veriable with the value true, but should it become false, 0 or 2 or stay the same? Of course it's possible to think of the boolean space as a one bit integer, so true+1 is false again, but I'd much rather see an error or warning. >And again not doing this complicaates php needlessly. For example the two >snippets below are different, tell me why: > >1) if (($p=strpos(...)+1) > 0) ... >2) $p = strpos(...); > $p++; > if ($p > 0) ... It should be the same indeed. >Sidenote: Why is the following a parser error: > if (($p=strpos(...))++ > 0) ... You can't increment ($p=strpos()), because it's not a left-value (=assignable variable). This already wasn't the case in C. The result of an assignment is the contents of the left-value and not it's location. Please also note that in C, the $p++ can lead to very strange results, because it's not very well defined when the incrementing is actually done. For example: *p++=i++; shouldn't become: ++i; *p=i; ++p; but: *p=i; ++p; ++i; or: *p=i; ++i; ++p; A C compiler can postpone all of the auto incrementing until after evaluating the actual expression, to avoid problems with expressions like: *p++=*p++ + *p++; (which is very dubious otherwise. Please also consider that in your case: ($p=strpos())++ would have as a result the value of $p after the assignment from strpos() and not of that plus on because $p would be increment after being read. I tend use ++p and ++i wherever appropriate in C and always in PHP. ++p always stands for (p+=1) but p++ is much more dubious. Greetings, Jaap