a =(a + b) - (b = a); C ++ vs php

时间:2013-08-04 07:54:36

标签: php c++ undefined-behavior

我一直在寻找并找到公式:a = (a + b) - (b = a)它应该交换两个变量(或某些情况下的对象)。不过我用C ++和php测试过,这些给了我不同的结果。

PHP:

$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
echo $a, " ", $b;

这会打印20 10

C ++

int a = 10;
int b = 20;
a = (a + b) - (b = a);
std::cout << a << " " << b;

这会打印10 10

代码看起来相同但输出不同,我一直在考虑两个原因:

  1. C ++代码正在编译,php正在解释。
  2. 此公式无用,因为它会导致未定义的行为。
  3. 有人可以解释一下,为什么C ++和php输出在这种情况下有所不同?

3 个答案:

答案 0 :(得分:14)

我不确定PHP中的规则是什么,但在C ++中,单个子表达式的顺序没有严格定义,或者作为技术术语,它是“未指定的” - 换句话说,允许编译器在b = a之前或之后计算a + b。只要在减法之前a + bb = a。使用“未指定”行为允许编译器在某些情况下生成更高效的代码,或者只是可以为某些体系结构构建编译器。

这也意味着如果你有一个表达式“重新计算”表达式本身的值,并在表达式的其他地方使用它,你会得到未定义的行为(简称UB)。 UB意味着这一点,行为没有定义 - 几乎任何事情都可能发生,包括你所看到的和许多其他选择(例如,编译器也允许产生42,即使逻辑说答案不会在这种情况下42 [这是错误的问题!])。

我还建议如果你想在PHP中交换两个值:

 $t = $a;
 $a = $b;
 $b = $t;

并在C ++中:

 #include <algorithm>

 std::swap(a, b); 

或者如果你坚持自己编写:

 int t = a;
 a = b;
 b = t; 

尝试聪明并且“没有临时变量”执行它几乎肯定会比使用临时变量更慢 - 当然在像C ++这样的编译语言中 - 在像PHP这样的解释语言中,创建一个新的变量可能添加一些额外的开销,但与所需逻辑的额外工作相比,它不太可能那么大。

答案 1 :(得分:3)

由于未定义的行为,C ++代码完全被破坏。 (在一个序列点中读写b)。

答案 2 :(得分:2)

对于PHP:

$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
//executes like thus
$a = (30) - ($b = $a);
$a = (30) - ($b = $a = 10); //new $a still not computed, using older $a
$a = (30) - (10);
$a = 20;
//then, $a=20 and $b = 10

这与Operator Precedence完全相关,在C中可能相同或者可能不相同,如果不发生意外行为,则取决于优先级。