【发布时间】:2020-06-15 08:36:25
【问题描述】:
据我了解,这个程序应该有未定义的行为。
#include <stdio.h>
int main()
{
int a = 3, b = 3, c = 10, d = 20;
int e = (a++ * ++b)-((c / b) * a) + d;
printf("%d", e) ;
return 0;
}
C99 标准 §6.5 ¶2 说
在前一个序列点和下一个序列点之间,一个对象应该有它的 表达式的评估最多修改一次存储的值。 此外,应仅读取先验值以确定该值 存储起来。
因此,在定义 'e'、a 和 b 的行中,不仅要确定要在 a 和 b 中存储什么,还要计算表达式 ((c / b) * a)
但是,即使使用-Wsequence-point warning,gcc 也不会发出警告。
我在这里错过了什么?
【问题讨论】:
-
gcc --version对于此类问题总是一个好主意。 -
@rici:ideone.com/NbV30F。那是 gcc 8.3
-
可能是 ideone 的问题,或者它没有使用您认为的警告选项。 Godbolt compiler explorer 按预期显示警告,我的本地 gcc 9.2.1 也是如此。
-
@nate tio.run 也是如此:(gcc 8.3.1) tio.run/##NYzLDoIwEEX3/YobjElrqaIuUX/…
-
我用 GCC 版本 7.2.0、7.3.0、8.1.0、8.2.0、8.3.0、9.1.0 和 9.2.0 测试,每一个都报告了
-Werror=sequence-point(错误因为我也用过-Werror)。这是在运行 macOS Mojave 10.14.6 的 Mac 上测试的。我在 2017 年 11 月至 2019 年 8 月之间构建了编译器,因此它们并非都构建在 Mojave 之上。
标签: c gcc language-lawyer