我正在阅读C陷阱和陷阱,并且读到以下代码可能对某些实现有效,而不会因为=和++的未定义顺序而对其他实现有效。 C仍然如此吗?
int i = 0;
while (i < n)
y[i] = x[i++];
如果是这样,那真的很不可思议。
答案 0 :(得分:5)
没有什么不可思议的。相当明确的未定义行为。详细了解sequence points。 只写作:
int i = 0;
while (i < n)
{
y[i] = x[i];
i++;
}
更安全,更易读。
答案 1 :(得分:3)
后缀++
包含结果和副作用。结果是操作数的当前值。 副作用是操作数增加1。问题出在的地方是,在评估表达式后不必立即应用副作用;它只需要在下一个序列点之前应用。
来自C语言标准(n1256):
6.5表达
...
2在前一个和下一个序列点之间,一个对象应具有其存储值 通过表达式的评估最多修改一次。 72)此外,先前的值 只读以确定要存储的值。 73)
...
72)浮点状态标志不是对象,可以在表达式中多次设置。
73)此段落呈现未定义的语句表达式,如允许的同时i = ++i + 1; a[i++] = i;
i = i + 1; a[i] = i;
答案 2 :(得分:1)
这段代码具有未定义的行为并不特别令人惊讶,因为它在语义上含糊不清:在y[i]
中,i
的值是什么?增量之前或之后的值? (请记住,=
运算符未指定在另一方之前评估一方)
答案 3 :(得分:0)
是的,它仍然是UB。
§1.9p7在某些特定情况下 执行顺序中的点 称为序列点,所有方面 以往评估的效果 是完整的,没有副作用 后续评估应具备 发生在。 (§1.9/ 7)
答案 4 :(得分:0)
嗯,i ++的意思是“在使用它的值后增加i”,所以我认为这是正确的(好吧,我改变了阅读其他帖子的想法)。相反,我会这样做:
while((i++) < n)
y[i] = x[i];