2017-03-08 135 views
0

我有以下結構:如何將C結構與4字節邊界對齊?

typedef struct LOG_EVENT 
{ 
    time_t time; 
    uint32_t count; 
    int32_t error_type; 
    uint16_t gm_state; 
    uint8_t gm_mode; 
    uint8_t mc_state; 
} LOG_EVENT; 

在32位的系統,所述結構的strict alignment是4字節,因此部件被分佈在4字節邊界對齊。在這種情況下沒有添加填充,因爲所有成員一起都是4字節對齊的。

但在64位系統上這不是真的,其中time_t是64位。這種情況下的strict alignment是8字節。

如何將對齊方式更改爲4字節?我想在64位系統上跨4個字節的邊界對齊,因爲我想確保沒有填充完成。

從海灣合作委員會的屬性頁https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html,它說,The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well

我沒有看到packed屬性接受任何參數。

另外,如果我使用如下的字節對齊,會造成任何問題,相對於4字節對齊:

typedef struct __attribute__ ((packed)) LOG_EVENT 
{ 
    time_t time; 
    uint32_t count; 
    int32_t error_type; 
    uint16_t gm_state; 
    uint8_t gm_mode; 
    uint8_t mc_state; 
} LOG_EVENT; 
+0

@yantantphil我不確定這是個好主意。 – Monku

+2

「在32位系統上,結構嚴格對齊是4字節」 - 錯誤....不!任何平臺上的對齊都不能保證。但隨時提供一個參考標準說明不同。這是一個像您的其他問題一樣的XY問題。 **爲什麼**你想要這種對齊?看起來你應該重新考慮你的整個設計。 – Olaf

+0

@Olaf我想要4字節對齊,因爲我不希望編譯器添加填充。如果你看看這個結構,考慮嚴格的對齊是8字節,最後增加4字節。 – Monku

回答

0

最直接的事情是...不使用time_t。僅使用固定寬度類型。

typedef struct LOG_EVENT 
{ 
    int32_t time; 
    uint32_t count; 
    int32_t error_type; 
    uint16_t gm_state; 
    uint8_t gm_mode; 
    uint8_t mc_state; 
} LOG_EVENT; 

你放棄處理符號的32位time_t(通常的範圍之外時間戳的能力,但並非總是如此,1901-12-13T20:45:52Z通過2038-01-19T03:14:07Z ),但如果您嘗試使用帶有32位時間戳的磁盤上記錄陣列(這是最合理的解釋),那不是問題。

1

#pragma pack(4)將對齊設置爲4個字節。

注意這個指令不是標準的一部分,這個標準最初是在MSVC中引入的,後來被gcc用來與微軟的編譯器兼容。

此外,請注意類型的大小,如time_t,size_t,並且所有指針類型都將在這些架構之間進行。如果你的意圖是在這兩種架構上運行的應用程序之間創建一個可理解的結構,這將是一個問題。

也知道使用64位應用程序沒有任何好處,除了您可以處理超過4GB內存的事實,如果您不需要可以堅持使用32位的所有內存,沒有罪。