c - 这是未定义的行为吗

标签 c gcc language-lawyer

根据我的理解,这个程序应该有未定义的行为。

#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;
}

The C99 standard §6.5 ¶2 says

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.



因此,在定义 'e' 的行中, ab被读取不仅是为了确定在 a 中存储什么内容和 b ,还要计算表达式 ((c / b) * a)
但是,即使使用 -Wsequence-point warning,gcc 也不会发出警告。 .

我在这里缺少什么?

最佳答案

使用 clang 编译器(版本 - clang-1001.0.46.4)编译时,收到以下警告:

   p.c:6:19: warning: unsequenced modification and access to 'b' [-Wunsequenced]
       int e = (a++ * ++b)-((c / b) * a) + d;
                        ^        ~
   p.c:6:14: warning: unsequenced modification and access to 'a' [-Wunsequenced]
       int e = (a++ * ++b)-((c / b) * a) + d;
                ^                     ~

来自 C11 标准#6.5p2 [强调]

2 If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)



该表达式调用未定义的行为。

编辑:

问题标记为 gcc ,所以为了回答的完整性,下面是使用 gcc 编译时的输出编译器 -Wall选项:
p.c:6:19: warning: operation on 'b' may be undefined [-Wsequence-point]
    int e = (a++ * ++b)-((c / b) * a) + d;
                   ^
p.c:6:14: warning: operation on 'a' may be undefined [-Wsequence-point]
    int e = (a++ * ++b)-((c / b) * a) + d;
              ^

请注意,如果我们没有指定任何选项(如 -Wall-Wsequence-point )到 gcc在编译时,它没有给出有关表达式的任何警告消息,但 clang 的情况并非如此。编译器。

关于c - 这是未定义的行为吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60499172/

相关文章:

c++ - 在定义明确的函数参数列表中传递未初始化的变量吗?

c - 如何让 XCode 6、LLVM 编译器检查 c 函数参数

c - 使用指针访问二维数组值

c++ - 逗号分隔的语句是否被视为完整语句? (和其他诊断问题)

c - 如何在 Windows 上更新安装 GCC 11.2

c++ - 为什么这是 C++ 中的前向声明?

c++ - gcc6.x 中的 constexpr 优化错误?

C循环复杂度

c - 局部变量的地址分配给结构体中的成员指针

是否可以将标签(分支目标)标记为 "volatile"以防止其被 GCC 优化触及?