事前及事后;C,C++;,爪哇,;C#

事前及事后;C,C++;,爪哇,;C#,c#,java,c++,c,C#,Java,C++,C,免责声明:这不是一个真实的例子。这只是这些语言如何工作的一个理论问题 C/C++、C#和Java在增量后和增量前操作符方面的具体区别是什么 这就是我从VC++10、Java1.6和C#4中得到的 在C++中,这是未定义的行为,所以任何答案都是正确的。有关更多详细信息,请参阅 不确定其他语言,但我认为这段代码也不正确 编辑: 参见Eric Lippert关于C#的回答。他否定了我对C的行为的假设。C++中的 < P>至少是这种未定义的行为。引用C++标准: 在上一个序列点和下一个序列点之间,标量对

免责声明:这不是一个真实的例子。这只是这些语言如何工作的一个理论问题

C/C++、C#和Java在增量后和增量前操作符方面的具体区别是什么

这就是我从VC++10、Java1.6和C#4中得到的


<>在C++中,这是未定义的行为,所以<强>任何答案都是正确的。有关更多详细信息,请参阅

不确定其他语言,但我认为这段代码也不正确

编辑:

参见Eric Lippert关于C#的回答。他否定了我对C的行为的假设。C++中的

< P>至少是这种未定义的行为。引用C++标准:

在上一个序列点和下一个序列点之间,标量对象的存储值最多应通过表达式的计算修改一次


我没有时间写详细描述C++、C、C和java之间的区别。我只想说,增量前后操作符的C#行为是完全指定的(在单线程场景中;如果您想知道它的原子性,多处理器弱内存模型中读写顺序的观察保证等,您可以自己进行研究)在C和C++中没有完全规定;编译器有着广泛的用途,可以随心所欲地对副作用进行重新排序。我从未使用过Java,所以我不会冒险猜测Java的功能

有关C#是什么的更多信息,请阅读C#规范。关于这个问题,请阅读我对这个问题的回答:

对于更短的拍摄时间:

C#表达式中的子表达式按优先级和关联性进行逻辑分组,然后从左到右进行计算。(例如,A()+B()*C()先计算A(),然后计算B(),然后计算C()。乘法“在”加法之前这一事实与此无关;子表达式总是从左到右求值。)

如果对子表达式的求值由于增量前或增量后的子表达式而导致副作用,则副作用会在生成结果之前立即发生。

Java和C#从左到右求值表达式,副作用会立即可见


<>在C++中,未指定子表达式求值顺序,在没有插入序列点的情况下修改同一对象两次是未定义的行为。

< P> java内存模型确保加载和存储的顺序完成,因此它应该在任何JVM上都相同(

)。

它看起来像C++,但是一旦你在一行上使用了两次,你就开始运行其他的东西(弗拉德就在那里)。如果你尝试其他C++编译器,你可能会发现它们有不同的答案。


我确信C#具有相同的操作顺序,但我猜它们有一个确保一致性的内存模型(如Java),但我在这里没有太多知识。

我喜欢这个问题,并找到了很好的解释,但我只想通过它的值以及如何评估来解释这个问题:

我将只讨论java和c/c++,因为我不了解c#

语句的计算方法如下

在java中

声明

int a= 2;                     a=2
int b= a++ + a++;             a=2, a=3

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=6

here value of a=7
int a= 2;                     a=2
int b= a++ + a++;             a=2, a=2

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=5

here value of a=7
在C/C++中

语句跟踪

int a= 2;                     a=2
int b= a++ + a++;             a=2, a=3

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=6

here value of a=7
int a= 2;                     a=2
int b= a++ + a++;             a=2, a=2

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=5

here value of a=7

简言之,在java中,表达式是从左到右的,因此在第二个“a”处,它将获取新值,在c/c++中,它将首先计算整个表达式,然后递增语句的所有操作数。

我非常确定,在语句中多次递增同一变量是未定义的行为。它在其他两种语言中定义良好。只是没有在C++中定义。你真的在现实生活中看到过这样的代码吗?如果你不能在头脑中计算出给定a值的答案(如果不在编译器中运行它),那么你就不应该编写它。编程已经够难了,因为它不会让你的生活变得如此艰难。你到底为什么要写这样的表达?看在上帝的份上,摆脱那种认为代码最好放在一行上,并且使用尽可能少的字符的想法。你需要这样的表达吗?或者你做这个实验是因为你对它好奇吗?不需要这样的表达——只是一个没有严格答案的理论问题。我会说:任何答案都是不正确的。它在其他两种语言中定义得很好。只是没有在C++@Kirill中定义:据我所知,从编译器的角度来看,未定义的行为意味着程序所做的任何事情都是正确的(包括格式化硬盘和启动鼻魔)。这种行为通常不是代码作者所期望的,这是一个完全无关的问题,也不是编译器的错。@Martin:请您指出一些用Java和C定义这种行为的文档好吗?只是好奇。@Vlad:我可能对Java错了。但是两种语言的设计者都从C++ NoOB看到了所有愚蠢的问题,并说我们不会被愚蠢的问题所分散,只需要定义行为。确切地说,人们说它在C#和Java中没有定义是完全错误的。如果不是麻烦的话,我会很感激的references@Nick:关于C,见(PDF),第6.5节,第2段;第6.5.2.4节,第2段。我目前无法进入C++标准,但语言基本上是相同的。@ NICK:java指定:“java编程语言保证操作符的操作数以特定的评估顺序,即从左到右进行评估。”对于C++,它是ISO/IEC 1488∶2003(E)第5节,^4.在pre&po方面,听起来你是最有前途的人