2012-12-05 103 views
11

可能重复:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
increment values in printf在C/C++为x [I] *值Y [i ++]总是等于x [I] * Y [I]

我有两个双数组xy和整数i。我的问题是,是否声明:

double res = x[i] * y[i++]; 

总是等于声明:

double res = x[i] * y[i]; 
i++; 

有没有可能是某些编译器会改变x[i] * y[i++]y[i++] * x[i],这显然会产生不同的结果?

+0

为什么这很重要?如果你想要一个特定的订单,只需按照这个顺序写。 –

+0

@BoPersson。我想解释为什么我需要它,但不想破坏这个问题。不久,我需要加速'double vectors_dot_product(double * x,double * y,int n);'函数,并发现'x [i] * y [i ++] + x [i] * y [i ++] +。 ..;'比'x [i] * y [i] + x [i + 1] * y [i + 1] + ...快;' – Serg

回答

13

否 - x[i] + y[i++]有未定义的行为。您正在修改i的值,并且还使用值i而没有中间顺序点,这会给出未定义的行为。


  1. 在C++ 11标准已经消除了“序列点”的术语,但效果是一样的 - 两个是无序相对于彼此。
+1

+1正确语言的第一个答案。 – slebetman

+3

这与乘法运算符的交换性无关。如果操作是'x [i] - y [i ++]'(这是不可逆转的),那么在这种情况下'i'的行为仍然是不确定的。 –

8

不,增量发生时未定义。

+8

不仅仅当增量出现时。行为**完全**未定义:它修改'i'并读取它的值而没有介入序列点。 –

+1

@佩特:太好了,比萨饼送货员什么时候会出现在我家门口? ;) – fredoverflow

+2

@FredOverflow - 询问你的编译器厂商。 –

1

否,

值的我+ + + i ++在在CC++undefined

如果您在表达式中同时读取两次变量并且写入它时,结果是未定义的。不要这样做。另一个例子是:

v[i] = i++; 

未定义表示其编译器依赖。
某些编译器可能会因为评估顺序而警告您未定义。 一个非常好的reference用于C++

1http://www.stroustrup.com/bs_faq2.html#evaluation-order

+0

仍然需要一点工作 - 'v [i] = i ++;'是未定义的,尽管它可能不涉及任何函数或传递参数。 –

+0

@GrijeshChauhan,谢谢你的链接。 – Serg

+0

@Serg:欢迎serg!我很高兴如果我可以帮助:) –

6

的代码修改i和使用它的值而没有插入序列点,所以该行为是未定义。语言定义在这里没有强制要求。

+0

有趣的是,在所有人中,你不会提到C++ 11不再使用“序列点”的事实。 :-) –

+0

@JerryCoffin - 有时候最好让事情简单些。 –

+0

+1。对于“放弃信仰,所有进入这里的人们”这种简单的说法,都有一些话要说。 –

相关问题