c - 为什么这些构造使用增量前和增量后未定义的行为?

标签 c increment undefined-behavior operator-precedence sequence-points

#include <stdio.h>

int main(void)
{
   int i = 0;
   i = i++ + ++i;
   printf("%d\n", i); // 3

   i = 1;
   i = (i++);
   printf("%d\n", i); // 2 Should be 1, no ?

   volatile int u = 0;
   u = u++ + ++u;
   printf("%d\n", u); // 1

   u = 1;
   u = (u++);
   printf("%d\n", u); // 2 Should also be one, no ?

   register int v = 0;
   v = v++ + ++v;
   printf("%d\n", v); // 3 (Should be the same as u ?)

   int w = 0;
   printf("%d %d\n", ++w, w); // shouldn't this print 1 1

   int x[2] = { 5, 8 }, y = 0;
   x[y] = y ++;
   printf("%d %d\n", x[0], x[1]); // shouldn't this print 0 8? or 5 0?
}

最佳答案

C 具有未定义行为的概念,即某些语言结构在语法上是有效的,但您无法预测代码运行时的行为。

据我所知,该标准没有明确说明为什么存在未定义行为的概念。在我看来,这只是因为语言设计者希望在语义上有一些余地,而不是要求所有实现以完全相同的方式处理整数溢出,这很可能会带来严重的性能成本,他们只是留下了行为未定义,因此如果您编写的代码导致整数溢出,任何事情都可能发生。

那么,考虑到这一点,为什么会出现这些“问题”?该语言清楚地表明某些事情会导致 undefined behavior 。没有问题,不存在“应该”的问题。如果在声明所涉及的变量之一时未定义的行为发生变化 volatile ,则不会证明或改变任何内容。它是未定义;您无法推理该行为。

你看起来最有趣的例子,是带有

u = (u++);

是未定义行为的教科书示例(请参阅维基百科的条目sequence points)。

关于c - 为什么这些构造使用增量前和增量后未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43714760/

相关文章:

c - 评估包含未初始化指针的条件 - IN,但它会崩溃吗?

c - 在无法到达的路径上具有未定义行为的程序的行为是否已定义?

c - 如何查找堆栈是向上还是向下增加?

python - 将从网络数据包接收到的字符串数据转换为结构

c++ - 混合 C 和汇编文件

c - C中的这段代码是否属于未定义行为类别?

c++ - std::map::iterator 在增量时使程序崩溃

c - GDK 线程不允许 gtk 更改(制作计时器)

swift - 无法使用类型为 (Int, @value Int) 的参数列表调用 "+="

c++ - 是否在失败/错误状态未定义行为的 istream 上调用 operator>>?