未定义的操作

时间:2013-09-10 20:46:20

标签: c mingw codeblocks undefined-behavior

今天我正在摆弄Code Blocks并收到一条好奇的警告信息。这不是一个错误,它编译并运行预期的结果,但警告信息引起了我的好奇心。

代码:

while (i < right)
    *(array + i) = *(buffer - left + i++);

while (i >= 0 && *(array + i) > key)
        *(array + i + 1) = *(array + i--);

给我一​​些错误消息,如:

  

警告:'i'上的操作可能未定义

但类似的代码:

if (l < left + middle &&
        (r == right || min == *(array + l)))
        *(buffer + i) = *(array + l++);
    else
        *(buffer + i) = *(array + r++);

未导致警告消息。请注意,所有代码段都来自同一个项目/文件。

2 个答案:

答案 0 :(得分:3)

赋值运算符不会导致序列点。因此,这一行:

    *(array + i + 1) = *(array + i--);

在没有插入序列点的情况下访问/修改i两次。这是你被警告的未定义行为。语言无法保证您在左侧i获得的价值。

答案 1 :(得分:1)

这是undefined behavior,因为您要修改i并在sequence points之间的另一个操作数中访问i的先前值,例如:

*(array + i) = *(buffer - left + i++);
          ^^                     ^^^

6.5 表达式 2 中的C99标准草案说:

  

在上一个和下一个序列点之间,对象应具有其存储值   通过表达式的评估最多修改一次.72)此外,先前值   应只读以确定要存储的值 .73)

并在脚注73 中提供了以下未定义行为的示例:

i = ++i + 1;
^^  ^^^
a[i++] = i;

注意,第一个示例与前面代码中指出的示例类似。