【问题标题】:Is post-increment operator guaranteed to run instantly?后增量运算符是否保证立即运行?
【发布时间】:2015-06-23 10:51:38
【问题描述】:

假设我有以下代码:

int i = 0;
func(i++, i++);

返回值后立即发生增量?是否保证第一个参数为0,第二个参数为1?

【问题讨论】:

  • 为什么垃圾代码不断在 SO 上发布,并要求解释为什么它是垃圾?避免这样的代码是否如此困难以至于必须提出问题? FFS 停止写废话,然后询问它。
  • @MartinJames 试图理解失败的原因有什么问题?
  • @MartinJames:因为新学习者还不了解什么是垃圾,什么不是垃圾。我们的工作是认真而耐心地教他们。您曾经对 C 的工作原理有误解吗?如果是这样,你不能因为一开始有同样的误解而责怪别人。
  • @iTayb:从到目前为止的答案和 cmets 中可以看出,您发布的代码可能会非常混乱。很难弄清楚代码应该做什么。事实上,编译器也无法弄清楚——不同的编译器会给出不同的答案,而且没有一个是错误的。这个特定的代码片段既未指定也未定义。如果你想让它有明确定义的行为,你必须引入一些序列点,也许可以写int first = i++; int second = i++; func(first, second);
  • @SteveSummit - 不,不是。教授和助教的教。 SO 贡献者回答来自专业和爱好者程序员的问题。如果对 OP 提供的代码有疑问,OP 应该简化它,也许使用一些中间临时变量,并在发布到 SO 之前进行测试/调试:(

标签: c c89 post-increment ansi-c


【解决方案1】:

这段代码被破坏有两个原因:

  • 在序列点之间访问变量两次,除了确定要存储哪个值之外,这是未定义的行为。函数参数的评估之间没有序列点。这意味着任何事情都可能发生,您的程序可能会崩溃和烧毁(或者更有可能显示不正确或垃圾值)。
  • 函数参数的评估顺序是未指定的行为,这意味着您无法知道将首先评估哪个。

Undefined behavior and sequence points

Why are these constructs (using ++) undefined behavior?

【讨论】:

  • 未指定的行为不会自行“破坏”代码。如果函数可以处理结果,则行为保持定义。
【解决方案2】:

不,您的代码是错误的。函数参数的求值之间没有序列点,两个对同一个对象有副作用的操作只有在它们被一个序列点分隔时才被允许。

C 中不存在“立即运行”的概念。最接近的可能是顺序操作的概念,其中上述顺序点强制分隔两个语句或表达式的执行。

【讨论】:

    【解决方案3】:

    是否保证第一个参数为0,第二个参数为1?

    没有。其未定义的行为。无法保证函数参数的求值顺序是从左到右或从右到左,即未指定求值顺序,因此对i 的副作用是未排序的。

    C11:6.5 表达式 (p2)

    如果标量对象的副作用相对于同一标量对象的不同副作用或使用同一标量对象的值的值计算是未排序的,则行为未定义 [...]

    【讨论】:

    • 你的解释与这是未定义的事实无关。
    • 还是好不了多少,它可能是不具体的,但仍然以一种或另一种方式排序。
    • @JensGustedt; 仍然以一种或另一种方式排序是什么意思?
    • 即使标准允许实现以任何顺序进行评估,它也可能会强制在每一个之间放置一个序列点。标准将此称为无定序。这适用于例如初始化列表中的初始化表达式。
    【解决方案4】:

    当你写i++时,你要求件事情发生:

    1. 获取i 的值并将其加一
    2. 将结果存回i

    现在,您必须了解的是,虽然 #1 会立即发生,但 #2 不会。思考#2 的正确方法是它发生在“某个时间之后”。这就是为什么我们不能说func(i++, i++); 做了什么。我们无法知道i++ 之一是否在第二个i++ 发生之前或之后将其结果存储回i

    【讨论】:

    • 不,错误的答案。这里没有“稍后”。如果硬件允许,编译器甚至可以同时并行计算这两个表达式。
    • 恕我直言,这不是一个“错误答案”,它只是一个故意简化的..
    • 不,这不仅是简化的,而且是错误的。一个发生在另一个之后(“稍后”)的想法给人一种错误的印象,即存储发生在增量本身“之后”。许多处理器都有用于这种操作的指令,因此它们在完全相同的时间“发生”。然后您对两个不同的i++ 的讨论也具有误导性。由于缺少序列点,代码是错误的,因此编译器可以在这里做任何事情。 (顺便说一句,反对票不是我的。)
    • @JensGustedt:我们正在强调不确定性的不同方面,仅此而已。是的,商店可能会随着增量立即发生——事实上,这就是海报的想法。但它也可能在增量之后的某个时候发生,发布者也必须理解这一点。张贴者想知道他是否可以保证得到 (0, 1),但他不是。他可能会得到 (0, 0)。 (当然他也可能得到 (1, 0),或者可能是一个非常奇怪和莫名其妙的结果。)
    猜你喜欢
    • 2023-03-20
    • 2020-07-14
    • 1970-01-01
    • 2010-10-14
    • 2016-02-02
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多