【问题标题】:Compound boolean expressions in C/PHP and variable assignmentC/PHP 中的复合布尔表达式和变量赋值
【发布时间】:2010-11-16 10:47:37
【问题描述】:

如果标题不完全符合我的要求,请原谅我,我很难准确地描述这个问题。

考虑以下 PHP 代码:

#!/usr/bin/php
<?php
class foo{
    function bar()
    {
        return true;
    }
}
if (true && $a = new foo() && $a->bar()) {
    echo "true";
} else {
    echo "false";
}

它给了

Fatal error: Call to a member function bar() on a non-object

对于 $a->bar();表达。

考虑以下 C 代码:

int main(void)
{
    int i = 0;

    if (i += 1 && printf("%d\n", i))
    {
        printf("Done: %d.\n", i);
    }
}

它输出:

0
Done: 1.

这是为什么?由于 C 和 PHP 声称将这些表达式短路并从左到右求值,因此我希望在左侧的表达式中设置的值可以在右侧的表达式中使用。我有什么遗漏吗?

【问题讨论】:

    标签: php c operators


    【解决方案1】:

    您现在的问题是运算符优先级。 PHP 目前会这样评估您的 PHP 语句:

    if (true && $a = ( new foo() && $a->bar() ) )
    

    在这种情况下,$a 未在您尝试调用 $a-&gt;bar() 时定义。

    你真正想要的是这个:

    if (true && ( $a = new foo() ) && $a->bar())
    

    在复杂的情况下使用方括号可以防止此类错误的发生。

    编辑:证明

    if(true && $a = true && false) { }
    var_dump($a); // bool(false)
    
    if(true && ( $b = true ) && false) { }
    var_dump($b); // bool(true)
    

    【讨论】:

    • +1。 C 代码示例也发生了同样的事情。如果您将 i += 1 放在括号中,它会执行 OP 的预期。
    • 枪的儿子,我从来没有想过操作员优先级。我一直认为分配操作与比较操作具有相似的优先级。快速浏览us3.php.net/manual/en/language.operators.precedence.php 提醒我,我经常误认为一个伟大的......很多......事情。
    • 不,thoriann,你错了。从被删除的另一个答案中。这永远不会有明确定义的输出:i = i++ + ++i; 它不依赖于线程,在语句中多次读取和写入变量是未定义的。
    • 我没有删除任何答案——我猜是发帖者删除了。在这种情况下,您看起来是对的,因为我们查看了生成的程序集,并且确实读取和写入在语句中作用于不同的值,因此为什么最右边的表达式没有更新的值。运算符优先级规则可能是由此产生的结果,或者反过来说,我真的不能说。
    • 我相信 thoriann 是正确的。 '&&' 保证了从左到右的评估,更重要的是,在(i += 1) 的评估之后和printf("%d\n", i) 的评估之前有一个序列点。这意味着i += 1 的副作用必须已经生效并在printf("%d\n", i) 的评估中可见。
    猜你喜欢
    • 1970-01-01
    • 2015-05-15
    • 2015-12-17
    • 1970-01-01
    • 2017-03-12
    • 2012-02-15
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    相关资源
    最近更新 更多