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++);


是未定义行为的教科书示例(请参见Wikipedia在sequence points上的条目)。

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

相关文章:

javascript - 如何使用 Javascript 将 <div> 从 0% 递增到 70% 进行动画处理?

c++ - 对象传递给 std::move 但未从中移出?

c - C 中静态分配数组大小的限制

c - 我可以用什么来替代管道的 GetFileSize() ?

c - 按值传递-不按我想要的方式执行

php - MYSQL INNODB 手动加锁自增

c 编程搜索文件中的字符串

javascript - 使用 jQuery 开始新的编号列表

c - C 是否与 C++ 中的 std::less 等效?

c++ - 是不是捕获了异常未定义的行为?