C 未定义操作

C 未定义操作,c,mingw,codeblocks,undefined-behavior,C,Mingw,Codeblocks,Undefined Behavior,今天我在摆弄代码块,收到了一条奇怪的警告信息。这不是一个错误,它以预期的结果编译和运行,但警告消息引起了我的好奇心 代码: 向我发送了错误消息,如: 警告:“i”上的操作可能未定义 但类似的代码: if (l < left + middle && (r == right || min == *(array + l))) *(buffer + i) = *(array + l++); else *(buffer + i)

今天我在摆弄代码块,收到了一条奇怪的警告信息。这不是一个错误,它以预期的结果编译和运行,但警告消息引起了我的好奇心

代码:

向我发送了错误消息,如:

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

但类似的代码:

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

没有产生警告消息。请注意,所有代码段都来自同一项目/文件。

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

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

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

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

    *(array + i + 1) = *(array + i--);
在没有中间序列点的情况下访问/修改i两次。这是你被警告的未定义的行为。该语言不保证为左侧的i获取的值。

这是因为您都在修改i并访问i在另一个操作数中的先前值,例如:

*(array + i) = *(buffer - left + i++);
          ^^                     ^^^
第6.5节第2段中的C99标准草案规定:

在上一个序列点和下一个序列点之间,对象应有其存储值 通过计算表达式最多修改一次。72此外,先验值 应为只读,以确定要存储的值。73

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

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

这是因为您都在修改i并访问i在另一个操作数中的先验值,例如:

*(array + i) = *(buffer - left + i++);
          ^^                     ^^^
第6.5节第2段中的C99标准草案规定:

在上一个序列点和下一个序列点之间,对象应有其存储值 通过计算表达式最多修改一次。72此外,先验值 应为只读,以确定要存储的值。73

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


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

Ah,感谢您的解释。这真的让我很烦。我只是想跳过额外的括号和-I行。不管怎样,还是做吧。再次感谢。啊,谢谢你的解释。这真的让我很烦。我只是想跳过额外的括号和-I行。不管怎样,还是做吧。再次感谢。
i = ++i + 1;
^^  ^^^
a[i++] = i;