【问题标题】:Is this an undefined behavior in C? [duplicate]这是 C 中未定义的行为吗? [复制]
【发布时间】:2018-05-03 06:29:59
【问题描述】:

我在 gcc 上运行我的 C 代码以了解前/后增量运算符。 然而,我看到的结果并不是我所期望的。就像第 6 行一样,因为 i 是 5,所以应该是

8 7 6 5 5

但它是8 7 6 5 8

然后到最后一行,它显示14 14 14 14。有人可以解释这种行为。我曾预料到 14 14 13 12

这个编译器是依赖的​​吗? printf函数在序列点上的行为是否未定义?

#include <stdio.h>

int main()
{
        i = 5;
        printf("%d %d %d %d %d \n", i, i++, i++, i++, i);
        printf("%d \n", ++i);
        printf("%d \n", ++i);
        printf("%d \n", ++i);
        printf("%d %d %d %d \n", i, ++i, ++i, ++i);

}

【问题讨论】:

  • 这是未定义的行为。 C 标准不支持您的期望
  • 无法解释,这是未定义的行为。您不能将同一变量的多个增量放入单个语句中。
  • 故事的寓意:在 99% 的情况下避免前后增量。你的代码的读者会很感激的。
  • @aschepler:建议的副本是关于 C++ 的。我确定有一个关于 C 的副本,但我没有找到它。
  • @ShankhadeepMukerji 你会想要仔细阅读C11 Standard 6.5.2.4 Postfix increment and decrement operators

标签: c post-increment pre-increment


【解决方案1】:

标准规定

在前一个序列点和下一个序列点之间,一个对象应该有它的 表达式的评估最多修改一次存储的值。 此外,应仅访问先验值以确定 要存储的值。

这些是您可以找到序列点的地方:

  • 在完整表达式(完整表达式 是一个表达式语句,或任何其他不是 任何较大表达式中的子表达式);

  • ||&amp;&amp;?: 和逗号运算符;和

  • 在函数调用中(在评估所有参数之后,并且 就在实际通话之前)。

对最后一点的阐述:函数调用中的逗号运算符是序列点,,s 之间的表达式可以按任意顺序计算。

检查thisthis 以获得更好的理解。

printf("%d %d %d %d %d \n", i, i++, i++, i++, i); 中,您在两个序列点之间多次写入同一内​​存位置,从而调用undefined behaviour

【讨论】:

  • 也许值得注意的是,分隔函数调用参数的逗号不是逗号运算符。
  • @aschepler 感谢您指出这一点。已编辑。
猜你喜欢
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
相关资源
最近更新 更多