C 这是未定义的行为吗
根据我的理解,这个程序应该有未定义的行为C 这是未定义的行为吗,c,gcc,language-lawyer,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; } #包括 int main() { INTA=3,b=3,c=10,d=20; INTE=(a++*+++b)-(c/b)*a+d; printf
#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;
}
#包括
int main()
{
INTA=3,b=3,c=10,d=20;
INTE=(a++*+++b)-(c/b)*a+d;
printf(“%d”,e);
返回0;
}
C99标准§6.5¨2规定
在上一个序列点和下一个序列点之间,对象应具有
通过表达式求值最多修改一次的存储值。
此外,应仅读取先前值以确定值
储存
因此,在定义'e'
的行中,读取a
和b
不仅是为了确定存储在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如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量对象的值进行的值计算不排序,则行为未定义。如果一个表达式的子表达式有多个允许的顺序,则如果在任何顺序中出现这种未排序的副作用,则该行为是未定义的。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;
^
请注意,如果我们在编译时没有为
gcc
指定任何选项(如-Wall
或-wsequencepoint
),它不会对有问题的表达式发出任何警告消息,但clang
编译器不是这样。gcc--version
对于此类问题总是一个好主意。@rici:。这就是gcc 8.3可能是ideone的问题,或者它没有使用您认为是的警告选项。锁销显示了预期的警告,我的本地gcc 9.2.1也是如此。@nate tio.run也是如此:(gcc 8.3.1)我使用gcc版本7.2.0、7.3.0、8.1.0、8.2.0、8.3.0、9.1.0和9.2.0进行了测试,每个版本都报告了-Werror=序列点
(错误,因为我还使用了-Werror
)。这是在运行macOS Mojave 10.14.6的Mac上测试的。我在2017年11月至2019年8月期间构建了编译器,因此它们并非都是基于莫哈韦构建的。