2010-08-12 56 views
0
typedef struct BaseMessage 
{ 
    int u32DeviceID : 32; 
    int u32CoreID : 32; 
    unsigned int u16Class : 16; 
    unsigned int u8OpCode : 8; 
    unsigned int u16CRC : 16; 
} BaseMessage; 

typedef struct MessageWithParameters 
{ 
     BaseMessage base; 
     int u8Param1 : 8; 
     int u8Param2 : 8; 
} MessageWithParameters; 

typedef struct FullMessage 
{ 
     int u32DeviceID : 32; 
     int u32CoreID : 32; 
     unsigned int u16Class : 16; 
     unsigned int u8OpCode : 8; 
     unsigned int u16CRC : 16; 
     int u8Param1 : 8; 
     int u8Param2 : 8; 
} FullMessage; 

int main() 
{ 
     printf("%d", sizeof(MessageWithParameters)); 
     printf("%d", sizeof(FullMessage)); 
} 

MessageWithParameters一個struct實例不會在BaseMessage本身需要一定的規模?
即使它在堆棧上?
我猜測編譯器將MessageWithParameters變成看起來像FullMessage的東西。
我正確嗎?兩個結構的尺寸都是一樣的,雖然他們中的一個在他們

+0

你爲什麼期望這些結構具有不同的尺寸,或者你問他們爲什麼有不同的尺寸? – nos 2010-08-12 08:45:35

+0

因爲BaseMessage基礎應該自行調整大小。我期望MessageWithParameters採用更大的尺寸,然後FullMessage,因爲MessageWithParameters包含BaseMessage。 – 2010-08-12 08:56:14

+0

它在我的機器上。雖然FullMessage和MessageWithParameters之間沒有關係 - 因此,您爲什麼認爲它們應該具有相同/不同的大小。 – nos 2010-08-12 14:19:00

回答

1

正如其他人說你遇到填充你的結構。 C語言本身沒有任何東西可以有效地阻止這一點。你的編譯器可能有一些擴展到東西,例如gcc實現這個爲attribute。但是,爲了讓事情真正包裝起來,那麼,你需要按照升序或降序重新排列你的領域,這樣對齊差距就越小越好。

此外,對這樣的結構使用位字段通常是一個壞主意。如果你有他們在下面使用C99固定大小的整數類型,如:

typedef struct BaseMessage 
{ 
    int32_t u32DeviceID; 
    int32_t u32CoreID; 
    uint16_t u16Class; 
    uint16_t u16CRC; 
    uint8_t u8OpCode; 
} BaseMessage; 

在這種情況下,如果在16位(罕見的,這些天)編譯器alignes你可以只用8個其他額外的浪費脫身BaseMessage的位。

+0

以及如果我對__attribute __((packed))做了什麼? – 2010-08-12 09:14:28

+1

這實際上取決於目標平臺的調整要求。您可以通過重新排序您的字段並提供'屬性'來放寬這些要求。但是,你真實存在的平臺上的結果取決於許多限制,特別是針對CPU的要求。無論如何,在大多數情況下,你會在最後有一個缺口,因爲我不認爲8比特邊界上的對齊依然存在。 – 2010-08-12 09:38:25

+0

我更喜歡使用結構來消耗盡可能少的內存,因爲它在以太網上傳輸。如何確保我的嵌入式設備和我的服務器pc在結構上具有相同的對齊方式? – 2010-08-12 09:53:11

2

你有一些填充問題,我猜。該基地有24位「遺留」,其中參數結構中添加的16位可以適應。你爲什麼使用位域?他們被普遍認爲是壞主意。

+0

壞主意?沒有。後?是。沒有「永遠做」或「永不做」。但是,以上述方式使用它們是一個糟糕的主意。 – adf88 2010-08-12 08:49:55

+0

位域有什麼問題? – Puppy 2010-08-12 08:54:52

+0

我正在使用它們來模擬嵌入式系統類型。比如Xuint32,Xuint16,Xuint8。 @ ad88:爲什麼這是一個壞主意? – 2010-08-12 08:58:34

1

我猜測編譯器會將MessageWithParameters變成看起來像FullMessage的東西。
我對嗎?

沒人可以這麼說。編譯器可以自由決定。該標準保證會員在第一個成員(包括派生成員)之前訂購併且沒有填充。

相關問題