簡體   English   中英

c 中初始化常量的 sizeof

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM