这个C代码仍然没有定义输出吗?

时间:2010-12-11 21:39:09

标签: c

我正在阅读C陷阱和陷阱,并且读到以下代码可能对某些实现有效,而不会因为=和++的未定义顺序而对其他实现有效。 C仍然如此吗?

int i = 0;
while (i < n)
    y[i] = x[i++];

如果是这样,那真的很不可思议。

5 个答案:

答案 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];