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

标签 c gcc compiler-construction icc

简单的示例程序:

#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 值和一个短整数的 union 中?其他编译器?我已经尝试过“-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。如果打印三个对象的地址,它们将是唯一的并且至少相隔一个字节。

关于c - 在各种编译器和优化级别下,bool 在 c 中的存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17886111/

相关文章:

C - Fclose -> 中止(核心转储)

c++ - 函数体内的url如何被编译

c - 如何在 C 中绘制 3D 图形?

c - 有没有更好的方法在分配后将变量转换为 'const'?

c - nop sled 后的 Shellcode 段错误

c# - 在 C# 中解析自定义格式文件

linux - Gcc编译 "cannot compute suffix of object files: cannot compile"

c++ - 使用 omp_set_num_threads() 将线程数设置为 2,但 omp_get_num_threads() 返回 1

ruby - 从源代码 : math. c:37 编译 Ruby 1.8.7 时出错:错误: token "("之前缺少二元运算符

c++ - 关于核心数的并行化限制