这是一个小程序.这应该打印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;
}
Run Code Online (Sandbox Code Playgroud)
这是从重新发布的CSmith测试中获得的,这里将更详细地讨论这种情况.
特别是,GCC,KCC和CompCert输出0,而MSVC 2010,ICC 12.0.2和最近的Clang输出1.
Ano*_*mie 12
有趣的问题.
根据C99标准草案6.5.17.1,类型(0, s.f1)
是相同的s.f1
,其(每6.7.2.1.9)是"由...组成1个比特的无符号整数型".这是一种算术类型,因为它是一个整数类型,它的精度是1(每6.2.6.2.6,6.6.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
,因此它被提升为(signed)int(根据6.3.1.1.2).然后由于两个操作数都是(带符号)整数,因此公共实数类型是有符号整数(根据6.3.1.8),因此比较结果应为0.
AFAIK,类型s.f1
是unsigned int
.我相信逗号操作符是一个红鲱鱼; 这种比较相当于int y = x >= s.f1;
.应用"通常的算术转换"(C99 6.3.1.8),在进行比较时x
转换为unsigned int
; 这种转换是明确定义的(它将导致UINT_MAX-2
.因此它会更大.所以答案应该是1
.