首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >位域与(负)整数、未定义的行为或编译器错误的比较?

位域与(负)整数、未定义的行为或编译器错误的比较?
EN

Stack Overflow用户
提问于 2011-07-14 22:50:18
回答 3查看 1.3K关注 0票数 15

这是一个小程序。这个打印应该是0还是1,或者它是否有未定义的行为?

代码语言:javascript
复制
#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。

EN

回答 3

Stack Overflow用户

发布于 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。

票数 12
EN

Stack Overflow用户

发布于 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

票数 5
EN

Stack Overflow用户

发布于 2011-07-15 05:02:26

我会在这里加上这个,这是来自Rajan Bhakta,here的评论#39,

这是标准中的一个歧义,在即将到来的最新版本的ISO标准(通常称为C1X,直到获得批准之前)的第6.3.1.1节第2段中已被清除。本质上,位域类型(来自逗号表达式的结果)被转换为整数,因此比较是带符号的整数比较。从本质上讲,C1X标准规定y的值为0。

如果有人能证实这一点,我将不胜感激。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6695193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档