foo(i)foo(i)是否在ANSI C中未定义?
这是一个示例代码段:
int i = 4,b; b = foo(i++) + foo(i++); 我很确定它不是未定义的,因为在调用foo之前有一个序列点.但是,如果我使用-Wall标志编译代码,则会生成编译器警告,警告:“i”上的操作可能未定义.我意识到它可能,但我只想仔细检查一下我是否正确. 解决方法
行为未定义.
b = foo(i++) + foo(i++); 正如你所说,在第一个i的评估和foo的调用之间存在一个序列点,同样在第二个i和call foo的评估之间也存在一个序列点.但是,在i的两次评估之间(或者更确切地说,在它们的副作用之间)(修改i)之间没有(必然的)序列点. 引用2011 ISO C标准的N1570草案,第6.5.2.2p10节:
第二句在这里意义重大:对i的两个评价是“不确定的 并且6.5p2说:
将这些放在一起,符合要求的实现可以按以下顺序评估表达式: >评估第一个i并将值保存在某处. 步骤1和2之间没有序列点,两者都修改i,因此行为未定义. (这实际上是一个轻微的过度简化;修改i的副作用可以与i的结果的确定分开. 底线:我们知道 b = i++ + i++; 由于已经反复解释的原因,它具有未定义的行为.在函数调用中包装i子表达式会添加一些序列点,但这些序列点不会将i的两个求值分开,因此不会导致行为定义得很好. 甚至是底线:请不要写那样的代码.即使行为得到了很好的定义,证明它并确定行为应该是更加困难. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |