2010-06-04 37 views
1

我想下面的代码打印11,但打印12,除了在后一种情况下,它打印10操作数的计算顺序+分配副作用

x=5; x1=x+(x=6); printf("%d\n",x1); 
x=5; x1=(x=x)+(x=6); printf("%d\n",x1); 
x=5; x1=(x+0)+(x=6); printf("%d\n",x1); 
x=5; x1=(x=5)+(x=6); printf("%d\n",x1); 

x=5; x1=(x=6)+x; printf("%d\n",x1); 
x=5; x1=(x=6)+(x=x); printf("%d\n",x1); 
x=5; x1=(x=6)+(x+0); printf("%d\n",x1); 
x=5; x1=(x=6)+(x=5); printf("%d\n",x1); 

GCC在任何情况下说:“警告: 'x'上的操作可能是未定义的'。

就是这样。

Bernhard

PS:没有问题,对不起。感谢您的回答。 :)
PPS:实际的代码是:

while (data-(data=read(adr)&(1<<6))) i++; 

我在ADR等6位停止切换。

+4

变异变量序列点之间两次是un定义的行为。因此,变异变量,然后读取它的值。 无论您期望得到什么样的价值,都是无效的假设。您应该重写代码以符合标准。 – 2010-06-04 21:24:54

+0

[任何人都可以解释这些未定义的行为(i = i ++ + ++ i,i = i ++等...)](http://stackoverflow.com/questions/949433/could-anyone-explain-these- undefined-behaviors-iiiii-etc) – 2010-06-04 21:25:46

+4

结果是,如您的编译器诊断,未定义。所以不要写这样的代码。 – 2010-06-04 21:26:23

回答

2

结果未定义,不需要进一步解释。但要说明两种可能的方式,编译器可以对待你的代码:

int x = 1; 
int n = (x=3) + x; 

编译器可以计算(X = 3)先在这种情况下,分配给n的值6.或者也可以先评估X在这种情况下,分配给n的值4

2

有警告的原因...序列点之间的评估顺序未指定。

+0

序列点之间的评估顺序*未指定*。 “未定义”是一个更强的术语,意味着该标准没有规定任何有关程序任何部分的行为。 – 2010-06-04 22:01:35

1

可以使用很少使用逗号操作,与其他变量一起,为了写你想要的循环:

while (lastdata = data, lastdata != (data = read(adr) & (1<<6))) i++;