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

Javascript 语言如何处理复合运算符的副作用?,javascript,c++,c,programming-languages,undefined-behavior,Javascript,C++,C,Programming Languages,Undefined Behavior,假设这种情况: int a = (--t)*(t-2); int b = (t/=a)+t; 在C和C++中,这是未定义的行为,如这里所描述的: 然而,在以下情况下,这种情况如何: JavaScript 爪哇 PHP C# 还有其他语言有复合运算符吗 我现在正在修复一个JavaScript -> C++端口,在很多地方都没有注意到。我想知道其他语言通常如何处理这个。。。没有定义的顺序是特定于C和C++的,不是吗?实际上,如果你必须询问或查找表达式的规则,你就不应该在代码中使用这个表达式。两

假设这种情况:

int a = (--t)*(t-2);
int b = (t/=a)+t;
<>在C和C++中,这是未定义的行为,如这里所描述的:

然而,在以下情况下,这种情况如何:

  • JavaScript
  • 爪哇
  • PHP
  • C#
  • 还有其他语言有复合运算符吗

我现在正在修复一个JavaScript -> C++端口,在很多地方都没有注意到。我想知道其他语言通常如何处理这个。。。没有定义的顺序是特定于C和C++的,不是吗?

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

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

然而,这种情况在:JS、Java、PHP、C#中是怎样的呢

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

拥有漂亮且精英化的花式代码是很好的,但绝对没有必要。当遇到这样的代码时,每种语言的解决方案都是添加两个分号(除非您使用的是python):

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

int b=t对于javascript,以下内容应该会有所帮助

本文明确说明了

a OP b OP c
从左到右,顺序是什么

我不知道其他语言。

根据,我相信javascript应该符合,在乘法和加法语句中,它先计算左手边,再计算右手边。(见11.5和11.6)。我认为这意味着代码应该与

t = t - 1;
int a = t * (t - 2);
t = t / a;
int b = t + t;
但是,您不应该总是相信规范与实现是相同的

在这种令人困惑的情况下,最好的办法是在原始操作环境中对模棱两可的代码行进行各种输入实验,并尝试确定它在做什么。确保测试能够证实假设的案例,也测试能够证伪假设的案例


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

也许最好不要知道:)@Daniel:完全同意!但是,对于OP来说,不幸的是,听起来好像他/她必须调试带有这种积垢的遗留代码……我认为最好在编写代码时不要知道它,而是在阅读代码时知道它。:)这个问题似乎是关于所有不是C++或C++的语言,标记C++和C真的有意义吗?是Java的答案,对于C#这并不能解决问题。斥责原始编码员无助于Kos破译原始javascript代码的模糊行为,并在c++中重现该行为。它确实解决了实际问题,即代码需要工作。要使代码正常工作,只需将其分解为单独的部分。只要佩伦一家完好无损,操作顺序就应该和我上面发布的一样。没有理由依赖复合运算符,尤其是当它们的行为未定义时。-1因为它没有解决这个问题,这与代码的好坏无关,而是顺序points@zzzzBov:除了预先存在的Javascript代码可能正在使用这些类型的表达式工作之外。分解你所说的这些表达式很容易,但是你怎么知道你在复制正确的行为呢?@David Thornley-并行运行现有代码和清理后的代码。如果重构改变了操作顺序,那么应该得到不同的结果。这不会告诉您原始代码是否真的执行了预期的操作,但它至少会告诉您是否更改了任何内容。不过,该链接没有明确说明是否需要在表达式的每一步重新读取变量的值。@Mark B:它看起来与C优先级表非常相似,副作用的顺序在C中没有定义。“你不应该在你的代码中使用这个表达式”-我认为这个问题的实际应用是,“我如何用等效的C++替换这个最初为Javascript设计的表达式?”。发问者知道自己的代码很糟糕,但除非他理解Javascript的表达式求值规则,否则他无法用等效的东西来替换它(假设原始作者也没有浪费大量的注释、文档或一组全面的测试用例,其中任何一个都可以解决任何歧义)。然后纯粹的理论部分是“其他语言呢”。@zzzzBov代码是一样的,我只是试图证明所做的选择,并提供调试/移植代码的策略。事实证明,操作符的副作用发生的顺序在ECMAScript.touché中有很好的定义。我想我从未明确提到JavaScript的ops顺序。
t = t - 1;
int a = t * (t - 2);
t = t / a;
int b = t + t;