英文原文:Why is f (i = -1, i = -1) undefined behavior?
问题:
最近在读 order of evaluation violations,其中的一个例子使我很困惑。
1)如果对一个标量对象的副作用相对于对这个标量对象的另一个副作用是无序的,那么这是未定义行为。
//代码片段
f(i=-1,i=-1);
//undefined behavior 未定义行为
在这段代码中,很明显 i 是一个标量对象。
算术类型(3.9.1),枚举类型,指针类型,指针成员类型(3.9.2),空指针类型和被 const 或 volatile 修饰的类型(3.9.3)等统称为标量类型。
从这句话中我看不出上面那句代码有什么分歧的地方。我认为不论第一个参数还是第二个参数先执行,i最终都是-1,并且两个参数的值都是-1。
有人能解释清楚这些吗?
最佳答案:
既然运算是无序的,也就不能说分配任务的指令不能交错执行。也许会选择最佳的方式去运行,由 CPU 的架构来决定。引用下面这句话来说明:
如果A在B之前是无序的并且B在A之前是无序的,那么存在两种可能性:
假设运算执行后,把-1 存进一个内存地址,就这个行为自身而言,这似乎并不会引发任何问题。但是如果一个指令和另一个指令交错执行操作同一个内存地址,你不能说编译器不会把这些指令优化成一个独立的具有同样效果的指令集,这样就会出错了。
例如,假想把内存清零然后再递减是最高效的。现在开始值是-1,然后就是:
f(i=-1,i=-1)
也许会变成:
clear i //清空 i
clear i //清空 i
decr i //递减 i
decr i //递减 i
现在i是-2。
这也许是一个假的例子,但可能是真的。
译文链接: http://blog.jobbole.com/62650/