当前位置: 首页 > 知识库问答 >
问题:

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

张绍晖
2023-03-14
#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?
}

共有1个答案

段干弘毅
2023-03-14

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

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

那么,考虑到这一点,为什么这些是“问题”呢?语言明确地说,某些事情导致未定义的行为。没有问题,没有“应该”的牵扯。如果当一个涉及的变量声明为volatile时未定义的行为发生了变化,那么这并不能证明或改变任何事情。未定义;你无法对这种行为进行推理。

你最有趣的例子是

u = (u++);

是一个未定义行为的教科书例子(参见维基百科关于序列点的条目)。

 类似资料:
  • 问题内容: 我最近为Eclipse安装了Checkstyle插件,并个人认为它很棒。但是它给我的警告之一有些晦涩。确切的警告是“ 不允许使用”。它是关于后缀在某行像 好的,我知道这是更好的迭代构造,但是它不能在所有地方都应用,有时老套是唯一的选择。 当我将行更改为 警告消失。我知道之间的区别,并和这一点我的生活我认为他们在标准的可互换建设。但是Checkstyle认为这是有害的(或容易出错)。 问

  • 为什么这不会增加?我正在批处理文件中使用这个。它做任何事情都是正确的,只是没有增加。我做错了什么? 编辑:这不是重复,这是一个完全不同的问题。

  • 问题内容: 我了解对此主题有很多疑问。但是我仍然有些困惑,不确定何时使用这些操作。我正在为参加考试而做的旧考试。其中一种方法返回可访问的残疾人可用教室的数量。我编写了counter方法,但不确定是应该先递增还是递后递增计数器。我对它如何与方法中的return语句混淆。我仍然不知道该方法将在下面返回什么值。其他问题未在方法中显示返回值,因此我对它的工作方式感到困惑。这是代码: 问题答案: 当您要在表

  • 如果我有: 很明显,这个表达式后面的应该是零,但我看到的任何地方,他们都说这个代码的行为是未定义的,而不仅仅是的值(直到减法之前)。 很明显,编译器可以简单地在变量中使用它认为“方便”的任何垃圾值,并且它将按照预期工作。这种方法有什么问题?

  • 问题内容: 我正在做一些有关Java的研究,发现这很令人困惑: 这是永无止境的循环! 有人很好地解释了为什么会发生这种事情吗? 问题答案: 上面的循环与以下内容基本相同:- 3 次你的一部分声明- ,被评估为: - 您需要从此处删除分配,以使其起作用:- (根据评论的OP请求) 的行为:- 就注释中指定的问题而言,以下表达式的结果:- 获得如下:- 让我们标记第二条语句的不同部分:- 现在,首先将

  • 问题内容: 当我偶然发现名为JSpeed-Javascript优化的项目时,我正在浏览Google Code。 我注意到优化之一是更改为for循环语句。 优化之前 优化后 我知道前后的增量是什么,但是知道如何加快代码速度吗? 问题答案: 这是我阅读并可以回答你的问题:“前递增()加一的值,然后返回;相反,收益则增加了一个给它,这 _在理论上_中创建一个临时变量存储的值的结果在执行增量操作之前”。