【发布时间】:2018-12-30 17:19:56
【问题描述】:
这个程序在我的机器上返回0:
#include <stdbool.h>
union U {
_Bool b;
char c;
};
int main(void) {
union U u;
u.c = 3;
_Bool b = u.b;
if (b == true) {
return 0;
} else {
return 1;
}
}
AFAICT,_Bool是一个整数类型,至少可以存储0和1,而true是整数常量1。在我的机器上,_Bool 有一个sizeof(_Bool) == 1 和CHAR_BITS == 8,这意味着_Bool 有256 个表示。
我在 C 标准中找不到太多关于 _Bool 的陷阱表示的信息,而且我无法找到是否使用不同于 0 或 1 的表示创建 _Bool(在实现支持两个以上的表示)是可以的,如果可以,这些表示是表示真还是假。
我可以在标准中找到当 _Bool 与整数进行比较时会发生什么,如果整数具有值 0,则将其转换为 0 表示,如果它具有值则转换为 1 表示它的值不是零,因此上面的 sn-p 最终会比较两个具有不同表示的_Bools:_Bool[3] == _Bool[1]。
我在 C 标准中找不到太多关于这种比较结果的信息。由于_Bool 是整数类型,我希望整数规则适用,这样相等比较仅在表示相等时才返回true,这里不是这种情况。
由于在我的平台上这个程序返回0,看来这个规则在这里不适用。
为什么这段代码会这样? (即我错过了什么?_Bool 的哪些表示是陷阱表示,哪些不是?有多少表示可以表示true 和false?填充位在其中扮演什么角色?等等)
关于_Bool 的表示,可移植的 C 程序可以假设什么?
【问题讨论】:
-
union 会导致 c 和 b 占用同一个内存区域,给 char 赋值 3 表示 b 的值也为 3,如果 NOT 为 true 则为 true,所以应该等于 -1 .
-
我可能是错的,但你的程序对我来说像是未定义的行为
-
为了避免整数溢出,对 _Bool 的任何非 0 (false) 赋值都存储为 1 (true)。话虽如此,您的代码似乎在这里造成了自己的混乱,因为代码显示
if (true) return false,然后您质疑为什么收到false响应。但是,我相信 @interjay 实际上有正确的答案,并且由于您的联合导致_Bool返回最低位,您的行为未定义。这似乎意味着联合仅用于识别一个值是奇数还是偶数。 -
否,如果 值 相等,则相等比较返回 true。陈述与此目的无关
-
My answer to Is it safe to memset bool to 0? 有很多可能有用的背景信息。