首页 > 解决方案 > 关于真实的表示可以假设什么?

问题描述

该程序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具有不同于0or的表示的 a 1(在支持两个以上表示的实现上)是否可以,如果可以,这些表示是真还是假。

我在标准中可以找到的是,当 a_Bool与整数进行比较时会发生什么,如果整数具有 value 则将其转换为0表示形式01如果它的值不为零则转换为表示形式,这样上面的代码片段就结束了比较_Bool具有不同表示的两个 s _Bool[3] == _Bool[1]:.

我在 C 标准中找不到太多关于这种比较结果的信息。由于_Bool是整数类型,我希望适用整数的规则,这样相等比较仅在表示相等时才返回 true,而这里不是这种情况。

由于在我的平台上该程序返回0,因此该规则似乎不适用于此处。

为什么这段代码的行为是这样的?(即我错过了什么?哪些表示_Bool是陷阱表示,哪些不是?有多少表示可以表示?填充位在其中扮演什么角色?等等。truefalse

可移植 C 程序可以对 的表示进行什么假设_Bool

标签: cboolean

解决方案


C11 标准中的脚注 122 说:

虽然 _Bool 对象中的位数至少为 CHAR_BIT,但 _Bool 的宽度(符号位和值位的数量)可能只有 1 位。

_Bool因此,在只有一个值位的编译器上,char当您从内存中将其读取为_Bool. 其他位是被忽略的填充位。

当我使用 GCC 测试您的代码时,_Bool成员在分配奇数时获得值 1,在分配偶数时获得值u.c0,这表明它只查看最低位。

请注意,上述内容仅适用于类型双关语。如果您改为将(隐式或显式强制转换) achar转换为 a ,如果 a非零_Bool,则该值将为 1 。char


推荐阅读