Re: incrementing boolean values

From: Date: Fri, 10 Jun 2005 08:01:10 +0000
Subject: Re: incrementing boolean values
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to internals+get-16601@lists.php.net to get a copy of this message
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

« previous php.internals (#16601) next »