这是一个小程序。这应该打印 0 或 1,还是它有未定义的行为?
#include <stdio.h>
struct S0 {
unsigned f1 : 1;
};
struct S0 s;
int main (void) {
int x = -3;
int y = x >= (0, s.f1);
printf ("%d\n", y);
return 0;
}
这取自重新发送的 CSmith测试,此案例讨论更多here .
特别是,GCC、KCC 和 CompCert 输出 0,而 MSVC 2010、ICC 12.0.2 和最近的 Clang 输出 1。
最佳答案
有趣的问题。
根据C99草案标准6.5.17.1,(0, s.f1)
的类型与s.f1
的类型相同,即(per 6.7.2.1.9) 是“由 1 位组成的无符号整数类型”。由于是整数类型,这是一种算术类型,其精度为 1(根据 6.2.6.2.6 和 6.2.6.1.3 暗示没有填充位),因此其秩小于 int
(根据 6.3.1.1.1 下的第二项;int 的精度至少为 15,因为它必须能够表示 -32767 到 32767 范围内的值(参见 5.2.4.2.1))。
由于 x
和表达式 (0, s.f1)
都具有算术类型,因此执行通常的算术转换(根据 6.5.8.3)。由于 int 可以表示 s.f1
的整个值范围,因此它被提升为(有符号)int(根据 6.3.1.1.2)。然后因为两个操作数都是(有符号的)整数,所以常见的实数类型是有符号的 int(根据 6.3.1.8),因此比较的结果应该是 0。
关于位域与(负)整数、未定义行为或编译器错误的比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6695193/