1

I was fiddling with Code Blocks today and got a curious warning message. It was not an error, and it compiled and run with expected result, but the warning message picked my curiosity.

Code:

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

and

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

got me error messages like:

warning: operation on 'i' may be undefined

but the similar code:

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

did not result in warning messages. Note that all snippets are from the same project/file.

4

2 回答 2

3

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

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

i在没有中间序列点的情况下访问/修改两次。这是您被警告的未定义行为。i语言不保证左侧的值。

于 2013-09-10T20:47:39.283 回答
1

这是未定义的行为,因为您正在修改i和访问序列点i之间另一个操作数中的先前值,例如这里:

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

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

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

它在脚注 73中给出了以下未定义行为的示例:

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

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

于 2013-09-10T21:35:37.637 回答