简体   繁体   English

在各种编译器和优化级别下在c中存储bool

[英]storage of bool in c under various compilers and optimization levels

trivial example program: 简单的示例程序:

#include <stdio.h>
main()
{
    bool tim = true;
    bool rob = false;
    bool mike = true;

    printf("%d, %d, %d\n", tim, rob, mike);

}

Using the gcc compiler it appearers, based on looking at the assembly output, that each bool is stored as a bit in individual bytes: 使用gcc编译器,它根据查看程序集输出的内容,将每个bool存储为单个字节中的位:

0x4004fc <main()+8>          movb      $0x1,-0x3(%rbp)
0x400500 <main()+12>         movb      $0x0,-0x2(%rbp)
0x400504 <main()+16>         movb      $0x1,-0x1(%rbp)

if, however, one turns optimization on, is there a level of optimization that will cause gcc to store these bools as bits in a byte or would one have to put the bools in a union of some bools and a short int? 但是,如果一个开启优化,是否有一个优化级别会导致gcc将这些bool存储为一个字节中的位,或者是否必须将bool放在一些bool和short int的并集中? Other compilers? 其他编译器? I have tried '-Os' but I must admit I can't make heads or tails of the output disassembly. 我试过'-Os',但我必须承认我不能做出输出反汇编的正面或反面。

A compiler can perform any tranformations it likes, as long as the resulting behavior of the program is unaffected, or at least within the range of permitted behaviors. 只要程序的结果行为不受影响,或者至少在允许的行为范围内,编译器就可以执行它喜欢的任何转换。

This program: 这个程序:

#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);

}

(which I've modified a bit to make it valid) could be optimized to the equivalent of this, since the behavior is identical: (我已经修改了一点以使其有效)可以优化到相当于此,因为行为是相同的:

#include <stdio.h>
int main(void)
{
    puts("1, 0, 1");
}

So the three bool objects aren't just stored in single bits, they're not stored at all. 因此,三个bool对象不仅存储在单个位中,它们根本不存储。

A compiler is free to play games like that as long as they don't affect the visible behavior. 编译器可以自由地玩这样的游戏,只要它们不影响可见行为即可。 For example, since the program never uses the addresses of the three bool variables, and never refers to their sizes, a compiler could choose to store them all as bits within a single byte. 例如,由于程序从不使用三个bool变量的地址,并且从不引用它们的大小,因此编译器可以选择将它们全部存储为单个字节中的位。 (There's little reason to do so; the increase in the size of the code needed to access individual bits would outweigh any savings in data size.) (没有理由这样做;访问单个位所需的代码大小的增加将超过数据大小的任何节省。)

But that kind of aggressive optimization probably isn't what you're asking about. 但这种积极的优化可能不是你所要求的。

In the "abstract machine", a bool object must be a least one byte unless it's a bit field. 在“抽象机器”中, bool对象必须至少为一个字节,除非它是一个位字段。 A bool object, or any object other than a bit field, must have an unique address, and must have a size that's a whole multiple of 1 byte. bool对象或除位域之外的任何对象必须具有唯一的地址,并且其大小必须是1字节的整数倍。 If you print the value of sizeof (bool) or sizeof tim , the result will be at least 1. If you print the addresses of the three objects, they will be unique and at least one byte apart. 如果打印sizeof (bool)sizeof tim ,则结果将至少为1.如果打印三个对象的地址,它们将是唯一的,并且至少相隔一个字节。

You would not use a union of bools. 你不会使用bools联合。 Instead you can say 相反,你可以说

struct a
{
unsigned char tim : 1;
unsigned char rob : 1;
unsigned char mike : 1;
} b;

b.tim=1;
b.rob=0;
b.mike=1;

and it would all get stored in a single char. 它将全部存储在一个char中。 However, you would not have any guarantees about how it's layed out in memory or how it's aligned. 但是,你不能保证它在内存中的布局方式或它是如何对齐的。

@Keith Thompson's good answer can explain what happened with the code example in the question. @Keith Thompson的好答案可以解释问题中代码示例发生了什么。 But I'll assume that the compiler doesn't transform the program. 但我会假设编译器不会转换程序。 According to the standard, a bool (a macro in stdbool.h the same as the keyword _Bool ) must have a size of one byte. 根据标准, boolstdbool.h的宏与关键字_Bool相同)必须具有一个字节的大小。

C99 6.2.6.1 General C99 6.2.6.1 概述

Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined. 除了位字段之外,对象由一个或多个字节的连续序列组成,其数量,顺序和编码要么是显式指定的,要么是实现定义的。

This means that any type(except bit-fields, including bool ) of objects must have at least one byte. 这意味着对象的任何类型(除了位域,包括bool )必须至少有一个字节。

C99 6.3.1.1 Boolean, characters, and integers C99 6.3.1.1 布尔,字符和整数

The rank of_Bool shall be less than the rank of all other standard integer types. 等级_Bool应小于所有其他标准整数类型的等级。

This means bool 's size is no more than a char (which is an integer type). 这意味着bool的大小不超过char (这是一个整数类型)。 And we also know that the size of an char is guaranteed to be one byte. 而且我们也知道char的大小保证是一个字节。 So the size of bool should be at most one byte. 所以bool的大小最多只能一个字节。

Conclusion: the size of bool must be one byte. 结论: bool的大小必须是一个字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM