[英]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.