[英]sizeof initialized constant in c
我編寫了簡單的示例代碼(也可在 ideone 獲得)來顯示我發現問題的地方。 Sizeof 在常量s
的情況下返回錯誤的結果。 波紋管是文件main.c
。
#include <stdint.h>
#include <stdio.h>
// comment this option if you know what is UB and want to avoit it
#define I_DONT_KNOW_WHAT_IS_UB ( 1 )
struct _sa {
uint32_t w;
uint8_t const a[];
};
uint8_t const a[] = { 7,6,5,4,3,2,1,0 };
struct _sa const s = {
.w = 8,
.a = { 7,6,5,4,3,2,1,0 },
};
char const b[] = "line";
int main(void)
{
#ifdef I_DONT_KNOW_WHAT_IS_UB
printf("sizeof(a) = %d \n", (int)sizeof(a)); // = 8
printf("sizeof(s) = %d \n", (int)sizeof(s)); // = 4
printf("sizeof(b) = %d \n", (int)sizeof(b)); // = 5
#else
printf("sizeof(a) = %zu \n", sizeof(a)); // = 8
printf("sizeof(s) = %zu \n", sizeof(s)); // = 4
printf("sizeof(b) = %zu \n", sizeof(b)); // = 5
#endif
return 0;
}
我使用舊的 ubuntu:
uname -a
Linux imbearr 4.4.0-148-generic #174~14.04.1-Ubuntu SMP Thu May 9 08:17:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
gcc --version
gcc (Ubuntu 9.3.0-11ubuntu0~14.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
gcc main.c -o szof -Xlinker -Map=szof.map
grep -C 1 "\bs\b" ./szof.map
0x00000000004005e8 a
0x00000000004005f0 s
0x00000000004005fc b
所以我通過 linker map 文件檢查了尺寸:0x4005fc - 0x4005f0 = 12、0x4005f0 - 0x4005e8 = 8。
為什么我有這樣的結果,這是 gcc 限制還是錯誤,可能是我的錯誤?
sizeof
返回參數類型的大小。
因此,當您調用sizeof(b)
時,您實際上是在問:“ struct _sa
的大小是多少? ”
struct _sa
的大小是 4 個字節,因為 element .w
占用 4 個字節,而 element .a
是一個靈活的數組,占用零字節,因為數組中定義的類型沒有定義大小。
詢問具有靈活數組成員的結構的大小僅給出結構的基本大小,而沒有數組成員。 C 2018 6.7.2.1 18 說:
… 在大多數情況下,靈活數組成員被忽略。 特別是,結構的大小就像省略了柔性數組成員一樣,只是它可能具有比省略所暗示的更多的尾隨填充......
因此, sizeof s
是如果靈活數組成員a
不存在時結構將具有的大小,除非它可能具有額外的填充。 由於uint32_t w;
member 需要四個字節,並且您的編譯器在這種情況下不會插入額外的填充,結構的大小是四個字節。
在這種情況下會出現額外的填充:
struct foo
{
char c;
int array[];
};
在int
需要四字節 alignment 的實現中,編譯器將通過在成員c
之后插入三個字節來確保數組成員對齊,因此sizeof (struct foo)
將為四。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.