该程序在我的机器上返回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
的陷阱表示的太多内容,也找不到创建_Bool
的表示形式与0
或{ {1}}(在支持两个以上表示的实现上)是可以的,如果可以,则这些表示是真还是假。
我可以在标准中找到将1
与整数进行比较,如果整数具有值_Bool
,则整数将转换为0
表示形式,然后0
(如果其值不为零),则以上代码段最终将两个1
与具有不同表示形式的_Bool
进行比较。
在C标准中,我找不到太多关于这种比较的结果。由于_Bool[3] == _Bool[1]
是整数类型,因此我希望整数规则适用,这样,等式比较仅在表示形式相等时才返回true,在此情况并非如此。
由于该程序在我的平台上返回_Bool
,因此似乎此规则不在此处应用。
为什么这段代码的行为如此? (即,我缺少什么?0
的哪些表示是陷阱表示,哪些不是??多少个表示可以表示_Bool
和true
?填充位对此起什么作用? ?等)
可移植的C程序可以假设false
的表示形式吗?
答案 0 :(得分:7)
C11标准中的脚注122说:
虽然_Bool对象中的位数至少为CHAR_BIT,但_Bool的宽度(符号位和值位的数量)可能仅为1位。
因此,在_Bool
仅具有一个值位的编译器上,当您以char
的形式从存储器中读取_Bool
的位时,只有其中一位有效。其他位是填充位,将被忽略。
当我使用GCC测试您的代码时,_Bool
成员在为u.c
分配一个奇数时得到的值为1,而在偶数分配时得到的值为0,这表明它只看最低的一个位。
请注意,以上内容仅适用于类型拼写。如果您将char
转换(隐式或显式强制转换)为_Bool
,则如果char
非零,则该值为1。