语言如何处理复合运算符的副作用?

时间:2011-02-14 13:56:16

标签: javascript c++ c programming-languages undefined-behavior

假设这种情况:

int a = (--t)*(t-2);
int b = (t/=a)+t;

在C和C ++中,这是未定义的行为,如下所述:Undefined behavior and sequence points

但是,这种情况如何:

  • 的JavaScript,
  • 爪哇,
  • PHP ...
  • C#
  • 嗯,还有其他有复合算子的语言吗?

我正在修改Javascript - >现在的C ++端口在很多地方都没有被注意到。我想知道其他语言通常如何处理这个问题...保留未定义的顺序对于C和C ++来说是某种特定的,不是吗?

4 个答案:

答案 0 :(得分:7)

根据我认为javascript应符合的ECMA Script specification,在乘法和加法语句中,它在评估右侧之前评估左侧。 (见11.5和11.6)。我认为这意味着代码应该等同于

t = t - 1;
int a = t * (t - 2);
t = t / a;
int b = t + t;

但是,您不应始终相信规范与实现相同!

在这样令人困惑的情况下,最好的办法是尝试对原始操作环境中模糊的代码行进行各种输入,并尝试确定它在做什么。确保测试可以确认假设的案例,并测试可以伪造它的案例。

编辑:显然大多数JavaScript都实现了ECMAScript的第3版,所以我将链接更改为该规范。

答案 1 :(得分:3)

实际上,如果您必须询问或查找表达式的规则,则不应在代码中使用该表达式。其他人将在两年后回来并弄错,然后重写并破坏代码。

如果这是一个严格的理论问题,我很遗憾无法提供有关其他语言的详细信息。

答案 2 :(得分:2)

对于javascript,以下article应该会有所帮助。

本文明确说明是否特定组合

a OP b OP c从左到右依次排列。

我不了解其他语言。

答案 3 :(得分:1)

  

然而,这种情况如何:JS,Java,PHP,C#...

坦率地说,int a = (--t)*(t-2); int b = (t/=a)+t;看起来像垃圾。

很高兴能拥有漂亮而精致的花哨代码,但绝对没有必要。面对这样的代码时每种语言的解决方案是添加更多的分号(除非你正在处理python):

--t;
int a = t * (t-2);
t /= a;
int b = t + t;
-or-
int b = t * 2;
-or-
int b = t << 1;
//whichever method you prefer

如果需要不同的操作顺序,则相应地调整线条。如果您正在尝试修复旧的错误代码, 修复代码 ,请不要只重新实施别人的意大利面。

编辑添加:

我意识到我从未专门回答原来的问题:

  

语言如何处理复合运算符的副作用?

较差。