# incrementing boolean values

- Thread: https://externals.io/message/16385
- Original archive: https://news-web.php.net/php.internals/16385
- Started by Johannes Schlueter on 2005-06-05T18:48:57+00:00
- Messages: 6
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #16385 — Johannes Schlueter — 2005-06-05T18:48:57+00:00

URL: https://externals.io/message/16385#16385

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

---

## #16389 — Derick Rethans — 2005-06-05T20:27:51+00:00

URL: https://externals.io/message/16385#16389 · In reply to: #16385

> 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?

I did this a year or so ago, and after discussing with Andi we decided 
not to promote types in this case.

Derick

-- 
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org

---

## #16400 — Marcus Boerger — 2005-06-06T06:37:13+00:00

URL: https://externals.io/message/16385#16400 · In reply to: #16389

Hello Derick,

Sunday, June 5, 2005, 10:27:51 PM, you wrote:

> 

> > […]

> I did this a year or so ago, and after discussing with Andi we decided 
> not to promote types in this case.

Not promoting types would mean adding false++, and true-- doesn't it?
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) ...

Sidenote: Why is the following a parser error:
   if (($p=strpos(...))++ > 0) ...
-- 
Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #16601 — Jaap van Ganswijk — 2005-06-10T08:01:10+00:00

URL: https://externals.io/message/16385#16601 · In reply to: #16400

At 2005-06-06 08:37, Marcus Boerger wrote:
>Sunday, June 5, 2005, 10:27:51 PM, you wrote:
> > […]

Yes, but I think it doesn't always do it in an
intuitive way and I would rather have errors
or warnings instead.

> > […]

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.

> > […]

 `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.

> > […]

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.?

> > […]
>
> > […]

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

---

## #16602 — Marcus Boerger — 2005-06-10T20:37:35+00:00

URL: https://externals.io/message/16385#16602 · In reply to: #16601

Hello Jaap,

Friday, June 10, 2005, 10:01:10 AM, you wrote:
> `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.

you shall never cast 0 to anything since 0 matches any pointer.
Casting it would result in a typecast error or an unneccessary
casting. Thus #define `NULL` 0 is the only way. But that apart :-)

> 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.

Yes you definitively come from C.

(...)

> 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.?

We had that before and theoretically there are more lists which nobody
uses anymore. And then i think it is a very good idea that the developers
get feedback. There is a lot of noise but still a fair amount of really
good mails here that help direct the way PHP evolves.

> > […]

> false is a constant and can't be increment.

It was a shortcut for $a=false; $a++; $b=true; $b--; of course. However
the shortcut is much easier to get.

> 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?

Since PHP conversion magic: true+1 => 2; false+1 => 1; 1+1 = >2

(...)

BTW, Nice commenting on the: ($p=strpos())++

Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #16611 — Jaap van Ganswijk — 2005-06-11T19:24:16+00:00

URL: https://externals.io/message/16385#16611 · In reply to: #16602

At 2005-06-10 22:37, Marcus Boerger wrote:
>Friday, June 10, 2005, 10:01:10 AM, you wrote:
> > […]
>
>you shall never cast 0 to anything since 0 matches any pointer.

0 is an integer and not a pointer and therefore I think
it should be cast. The idea behind `NULL` seems to be that
it's not an integer but stands for a pointer containing
zero. I think that both ideas shouldn't be mixed.

I think there is no sense of writing (in C):

int i=NULL;

instead of:

int i=0;

>Casting it would result in a typecast error

It shouldn't be an error to cast a value of a
certain type into that same type and in most
languages it isn't, so:

int i;

i=(int)i;

should never be a problem and certainly not in a
language like PHP where it's not always clear
of what type the source is.

>or an unneccessary casting.

Casting in PHP is more meant to make sure that
the result is of a certain type, as far as I
understood it.

>Thus #define `NULL` 0 is the only way. But that apart :-)

I plead for `NULL` being something else than 0.

And the macro mechanism of using things like
'#define' is so outdated!

> > […]
>
> > […]
>
> > […]
>
> > […]
>
> > […]
>
>Yes you definitively come from C.
>
>(...)

PHP is also based on C, so what is your point?

I think that all modern C-like languages should
as much as possible be alike, because a lot of
programmers will want to or even have to be able
to write in several languages.

It's not easy to remember all of these details and
especially slight differences about languages like
C, C++, Javascript, Java and PHP.

However, things progress and since PHP is now in
the forefront of developments, I think, it should
try to use the best solution to these problems or
at least openly discuss them.

I mis that a lot on this mailing list. Crucial
decisions seem to be made by a few implementers
and solutions are borrowed from other languages
seemingly at random.

Example, who ever came up with:

foreach ($A as $d)

instead of:

foreach ($d in $A)

(or why not allow both?)

> > […]
>
>We had that before

The fact that it was discussed before doesn't
make the idea less valid.

I am and was on this and other PHP mailing lists
and never noticed a different mailing list to
discuss the design of PHP itself, but I'd
very much like to be on such a list, because
I could have prevented a lot of folly, like
just adding file_getcontents() and not
file_putcontents() (or whatever the exact
name of the function is).

I don't expect that all ideas are actually
implemented and I don't believe in
committee languages (like Algol and Ada) and
don't mind when say Rasmus keeps the final say
in matters (so the language stays consistent
and small), but I think we should freely
discuss ideas and not in this environment of
implementers and users. Design is very different
from implementing and use. Of course everyone
is welcome to join the design mailing list,
but on this list, about 95% is about
implementation and version issues and that
is more of a hindrence for design issues.

Thinking about design issues should look ahead
5 years or so and implementers just think about
what can be done and not what should be done
and a lot of people (users and implementers)
can only think in terms of what is and that
it should be preserved as is.

And yes, as a programmer and designer I know
that one has to consider compatibility issues
in a project like PHP, but since PHP is still
growing fast, it's much better to implement
changes sooner than later.

BTW. I also had some significant ideas for
improving C and (pre-RISC) assemblers. I posted
some of them on the 6811 mailing list but when
the 6812 came out, they clearly hadn't read them...
(I'll gladly repeat them here and once you have
read them you'll forever wonder why the old
designs were so flawed.)

As regards suggestions for C: I did have contact
with someone on the C design committee back in
the early ninetees and that was before these
things could be done via mailing lists. I'll
gladly explain my ideas, based on porting
applications between all kinds of architectures
among which porting them to a 64 bits architecture
(from Xenix on a 486 to a DEC's Alpha) and back
again to a Duron running Linux.

>and theoretically there are more lists which nobody
>uses anymore.

I think that is not a theoretical but a practical
problem. ;-)

And yes, I know a lot about the dynamics of
mailing lists and therefore also about dead lists
and that is why I proposed a split, which means that
an existing list like this is being split into two
lists which both have the same subscribers and
whereby people are encouraged to post on the right
list and unsubscribe from one of the lists when they
are not longer interested. I'd unsubscribe from the
implementation and version part of list. Personally
I always wait until there is a stable new PHP version
and compile that and my system (when my latest
upgrade of Mandrake didn't unstall a new enough
PHP version).

>And then i think it is a very good idea that the developers
>get feedback.

Of course, but I don't think that the developers (read
implementers) should also be the designers, or should
decide about the design issues. Of course they can
involve themselves in the design issues if they like,
but there is a much lower than 100% overlap in skills.
I have been a for-pay programmer and although I have
studied industrial design for a few years before
graduating in computer science, I had no problem with
the fact that someone else designed a product and I
only had to write the code (although I usually had
to fill in a lot of design details... ;-)

>There is a lot of noise but still a fair amount of really
>good mails here that help direct the way PHP evolves.

As far as I can tell, more than about 95% is noise as
regards to pure design of PHP and I can't read it all
to see if there is anything relevant to the direction
of PHP.

In fact I got involved with this discussion when I
was considering unsubscribing from this mailing list.

> > […]
>
> > […]
>
>It was a shortcut for $a=false; $a++; $b=true; $b--; of course. However
>the shortcut is much easier to get.

Sorry, but I am used to write for computers and they
wouldn't understand such an abstraction... ;-)

> > […]
>
>Since PHP conversion magic: true+1 => 2; false+1 => 1; 1+1 = >2

Yes, but that is when you consider current PHP laws
to be *god-given*, but I was discussing how it should
be (and I thought you were too).

And I think that programming languages shouldn't
have this and similar magic, but be more strict
so that programming errors are spotted earlier.

>BTW, Nice commenting on the: ($p=strpos())++

Well I used to write my own C compilers, so I know
a lot about the details of C. The second K&R book
(the ANSI version) answers all questions that a
compiler writer has. C was so well defined,
unlike Pascal for example and it was so easy to
translate C source code into fast machine code.
C was clearly a great revolution in computer
languages.

But we are now witnessing another revolution in
the form of script languages and PHP is in my
view at the very forefront (and yes, I have
studied Perl, Python and Ruby) and would very
much like to help iron out problems with PHP
before they are implemented and reverse earlier
mistakes (can we ever get rid of that damned '$'? ;-)

BTW. In university (here in the Netherlands) I
followed an optional course by professor Lambert
Meertens about the language ABC that later
inspired Guido van Rossum to design Python...

Greetings,
Jaap

http://www.chipdir.org/
