8

The result of:

var_dump(null != $a = 15);
var_dump($a);

is:

bool(true)
int(15)

Why is this script not triggering an error? Since != (not equal operator) has a higher precedence than = (assignment operator), $a should be compared to null first?

VolkerK
  • 95,432
  • 20
  • 163
  • 226
Baptiste Costa
  • 1,044
  • 1
  • 12
  • 24
  • definitely weird. `$a == null = 15` gives false dumps too. And putting in `(null != $a) = 15` does spit out an unexpected `=` error. – Marc B Oct 26 '15 at 15:48
  • 1
    What alternative to interpreting it as `null != ($a=15)` is there? With `(null !=$a)=15` you'd try to assign the value 15 to a boolean value; that doesn't work. – VolkerK Oct 26 '15 at 15:56
  • @VolkerK this is an example, this script has no real life purpose! My reflection starts with this kind of expression that I see (and use) a lot `if (!$a = foo())`. – Baptiste Costa Oct 26 '15 at 16:00
  • and then the same thing applies. How would you you assign a value to (!$a) ? – VolkerK Oct 26 '15 at 16:04

2 Answers2

7

The only reason I can find is that the documentation says that this is still legal: http://php.net/manual/en/language.operators.precedence.php#example-129

It seems to be an exception to what is shown in the table above.

Josef Engelfrost
  • 2,955
  • 1
  • 29
  • 38
  • 3
    I think one other thing to note is the following comment on readability: "Use of parentheses, even when not strictly necessary, can often increase readability of the code by making grouping explicit rather than relying on the implicit operator precedence and associativity." – Paul Bain Oct 26 '15 at 15:57
  • It's not a "deliberate exception"; there is no addional lexer rule to explicitly "allow" this. It's just the normal way it works. The example in the manual is just a reminder for developers who wonder. – VolkerK Oct 26 '15 at 16:05
  • But it does seem to be an exception from the table at the top of the page, is it not? Even if there is no explicit rule in the parser/lexer, it seems to be an exception to the previous explanation. – Josef Engelfrost Oct 26 '15 at 16:09
  • @VolkerK Adjusted my wording, would you consider it more correct now? – Josef Engelfrost Oct 26 '15 at 16:13
  • Not really. There is no exception involved; it's merely something developers wonder about. – VolkerK Oct 26 '15 at 16:26
  • 3
    There is a rule of operator precedence, this expression clearly breaks the rule, this is called an exception. No big deal though, I'm moving on... – Baptiste Costa Oct 26 '15 at 16:28
4

This is not about operator precedence but about: operator precedence lists don't tell you the details (really, they never do), e.g. about the bison rules and the resulting pattern matching and stack reducing.
Let's take the statement null != $a = 15;, for simplicity without the var_dump.
This is how the parser "sees" this statement - or: sees that it is a statement.
(I hope this will be rendered with a fix-width font everywhere...)

null                       !=                    $a                                  =   15                           ;
                                                 T_VARIABLE                           
identifier                                       compound_variable                       T_LNUMBER
namespace_name                                   reference_variable                      common_scalar
general_constant                                 base_variable                           scalar
scalar                                           base_variable_with_functions_calls      expr_without_variable
expr_without_variable                            variable                            =   expr
expr                       T_IS_NOT_EQUAL             \______ expr_without_variable _________/
   \__________________    expr ____________________________________________/                                          ;
                           \_________________       unticked_statement _______________________________________________/
                                                     statement                                 

( You can look up the rules at https://github.com/php/php-src/blob/PHP-5.6.15/Zend/zend_language_parser.y )

There's no special rule for the assignment operator in this case; there simply isn't another way for the parser to match the statement, so precedence doesn't apply.

VolkerK
  • 95,432
  • 20
  • 163
  • 226