Calling Conventions – when you need to know C to understand PHP

I think most of the people using PHP wonder from time to time about particular behavior of the language. That’s pretty much the same case with every language. Pythoneers have their wtf moments, Ruby programmers have their wtf moments and C programmers tend to live in a whole wtf universe. But lately I stumbled over a nice one. It looked like a bug in PHP, but turns out to be an interesting, curious, part of the C-language. Imagine the following PHP code sample and note that $a and $b are not defined (yeah I know, it’s bad coding style..blabla..):

<?php
var_dump($a + $b);
?>

What is the expected result with error_reporting set to E_ALL?

PHP Notice: Undefined variable: b in /var/foo/bla on line 1
PHP Notice: Undefined variable: a in /var/foo/bla on line 1
.
Are you sure? I’m not. On x86 hardware b is fetched before a is fetched and therefore the executor detects that b is not set first. But wait. Let’s test this on a SPARC machine:

PHP Notice: Undefined variable: a in /var/foo/bla on line 1
PHP Notice: Undefined variable: b in /var/foo/bla on line 1
.
What? It evaluates it in the reversed oder? What is happening? So I spend a few minutes with my lovely debugger and it turns out that this is what happens in the engine (I use pseudo code here):

result ZEND_ADD_OPCODE()
{
   return add_function(get_op1(), get_op2());
}

Voila, that’s the problem. On SPARC get_op1() is executed before get_op2(), while it’s the other way round on x86. As get_opX() detects if a variable exists, the error messages appear in reversed oder. I did a little bit research (thank you SunCC Team for your answer!) and it turned out, that C99 doesn’t define the way function calls in parameter lists are executed. Therefore, every system and compiler is free to use it’s own ordering mechanism. My current plan: Write a compiler that does this by random(). The fix is trivial:

result ZEND_ADD_OPCODE()
{
  op2 = get_op2();
  return add_function(get_op1(), op2);
}

. It’s a lovely curiosity.

One thought on “Calling Conventions – when you need to know C to understand PHP

  1. Johannes

    Just a small comment: PHP doesn’t follow C99 but C89 as not al supported compilers are C99-ready, while stuff like C99 types might be nice … but well, doesn’t matter for this case ;-)

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>