[英]storage of bool in c under various compilers and optimization levels
简单的示例程序:
#include <stdio.h>
main()
{
bool tim = true;
bool rob = false;
bool mike = true;
printf("%d, %d, %d\n", tim, rob, mike);
}
使用gcc编译器,它根据查看程序集输出的内容,将每个bool存储为单个字节中的位:
0x4004fc <main()+8> movb $0x1,-0x3(%rbp)
0x400500 <main()+12> movb $0x0,-0x2(%rbp)
0x400504 <main()+16> movb $0x1,-0x1(%rbp)
但是,如果一个开启优化,是否有一个优化级别会导致gcc将这些bool存储为一个字节中的位,或者是否必须将bool放在一些bool和short int的并集中? 其他编译器? 我试过'-Os',但我必须承认我不能做出输出反汇编的正面或反面。
只要程序的结果行为不受影响,或者至少在允许的行为范围内,编译器就可以执行它喜欢的任何转换。
这个程序:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
bool tim = true;
bool rob = false;
bool mike = true;
printf("%d, %d, %d\n", tim, rob, mike);
}
(我已经修改了一点以使其有效)可以优化到相当于此,因为行为是相同的:
#include <stdio.h>
int main(void)
{
puts("1, 0, 1");
}
因此,三个bool
对象不仅存储在单个位中,它们根本不存储。
编译器可以自由地玩这样的游戏,只要它们不影响可见行为即可。 例如,由于程序从不使用三个bool
变量的地址,并且从不引用它们的大小,因此编译器可以选择将它们全部存储为单个字节中的位。 (没有理由这样做;访问单个位所需的代码大小的增加将超过数据大小的任何节省。)
但这种积极的优化可能不是你所要求的。
在“抽象机器”中, bool
对象必须至少为一个字节,除非它是一个位字段。 bool
对象或除位域之外的任何对象必须具有唯一的地址,并且其大小必须是1字节的整数倍。 如果打印sizeof (bool)
或sizeof tim
,则结果将至少为1.如果打印三个对象的地址,它们将是唯一的,并且至少相隔一个字节。
你不会使用bools联合。 相反,你可以说
struct a
{
unsigned char tim : 1;
unsigned char rob : 1;
unsigned char mike : 1;
} b;
b.tim=1;
b.rob=0;
b.mike=1;
它将全部存储在一个char中。 但是,你不能保证它在内存中的布局方式或它是如何对齐的。
@Keith Thompson的好答案可以解释问题中代码示例发生了什么。 但我会假设编译器不会转换程序。 根据标准, bool
( stdbool.h
的宏与关键字_Bool
相同)必须具有一个字节的大小。
C99 6.2.6.1 概述
除了位字段之外,对象由一个或多个字节的连续序列组成,其数量,顺序和编码要么是显式指定的,要么是实现定义的。
这意味着对象的任何类型(除了位域,包括bool
)必须至少有一个字节。
C99 6.3.1.1 布尔,字符和整数
等级_Bool应小于所有其他标准整数类型的等级。
这意味着bool
的大小不超过char
(这是一个整数类型)。 而且我们也知道char
的大小保证是一个字节。 所以bool
的大小最多只能是一个字节。
结论: bool
的大小必须是一个字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.