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

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to