这是一个小程序。这个打印应该是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,而MSVC2010、ICC12.0.2和最近的Clang输出为1。
发布于 2011-07-15 00:06:02
这个问题很有趣。
根据C99草案标准6.5.17.1,(0, s.f1)的类型与s.f1的类型相同,后者(根据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和expression (0, s.f1)都具有算术类型,因此执行通常的算术转换(根据6.5.8.3)。由于整型可以表示s.f1的所有值范围,因此它被提升为(带符号的)整型(根据6.3.1.1.2)。然后,由于两个操作数都是(有符号的)整数,所以公共实数类型是有符号的整数(根据6.3.1.8),因此比较的结果应该是0。
发布于 2011-07-14 22:55:47
AFAIK,s.f1的类型为unsigned int。我认为逗号操作符是在转移注意力;这种比较等同于int y = x >= s.f1;。应用“通常的算术转换”(C99 6.3.1.8),在进行比较时将x转换为unsigned int;这种转换是明确定义的(它将导致UINT_MAX-2。因此,它将会更大。所以答案应该是1。
发布于 2011-07-15 05:02:26
我会在这里加上这个,这是来自Rajan Bhakta,here的评论#39,
这是标准中的一个歧义,在即将到来的最新版本的ISO标准(通常称为C1X,直到获得批准之前)的第6.3.1.1节第2段中已被清除。本质上,位域类型(来自逗号表达式的结果)被转换为整数,因此比较是带符号的整数比较。从本质上讲,C1X标准规定y的值为0。
如果有人能证实这一点,我将不胜感激。
https://stackoverflow.com/questions/6695193
复制相似问题