2014-12-03 22 views
0

我目前正在研究嵌入式代碼的端口(在飛思卡爾S12),所以GNU和我有一個工會的問題。 我有以下工會工會和內存對齊方面的問題

typedef signed short  sint16; 
typedef signed long   sint32; 

typedef union 
{ 
    sint32 Akku; 
    sint16 AkkuHigh; 
    sint16 AkkuLow; 
} akku_type; 

,我想進入聯盟的最高2字節。問題是,AkkuHigh和AkkuLow都和Akku有相同的起始地址。它似乎是編譯器特定的。我的問題是: 是否有一個編譯器標誌可以改變工會的行爲? Can atribute((align(2)))help me?

預先感謝您

+0

在內部匿名'struct'中打包'high'和'low'字段。嚴格地說它不是可移植的,但它應該工作。 – 2014-12-03 17:44:13

+1

你爲什麼期望他們有不同的地址? – Borgleader 2014-12-03 17:45:14

+0

@ ParkYoung-Bae:C允許它,它是一個常見的C++擴展。想知道爲什麼委員會沒有陷入並使其合法化... – Deduplicator 2014-12-03 17:50:08

回答

3

是的,所有的AkkuAkkuHighAkkuLow具有相同的地址。這就是unions在C中的工作方式。通過它的外觀,你打算與一個32位成員和一個由兩個16位成員構成的成員進行聯合。你寫的不是實現它的方法。嘗試改爲:

typedef union 
{ 
    sint32 Akku; 
    struct s { 
     sint16 AkkuHigh; 
     sint16 AkkuLow; 
    } representation; 
} akku_type; 
+0

確保'AkkuHigh'是高位字節,'AkkuLow'是低位字節?編譯器能否決定切換它們? – Unapiedra 2014-12-03 17:45:50

+0

@Unapiedra保證是一個結構的成員地址是正確的。這些地址對應的是依賴於實現的(通常,這取決於目標體系結構的字節順序。結構如同大多數大端體系結構所寫的那樣)。 – 2014-12-03 17:48:17

+0

@Unapiedra:不允許切換它們,但在'struct'-members之後添加任意(實現定義的)填充量是(* not * before)。 – Deduplicator 2014-12-03 17:57:34

0

該聯合的正確定義可在this answer中找到。

atribute(align(2))一定會幫助你,如果你在32位或64位體系結構上編譯它。另外,在64位sizeof(sint32)上是8(64位)。

根據體系結構的序列性,您可能需要更換AkkuHighAkkuLow

+0

只要提到這是有效的C但不是C++,儘管它是C++中的常見擴展。 – Deduplicator 2014-12-03 17:53:26

+0

什麼是無效的C++?未命名的結構? – axiac 2014-12-03 17:54:44

+0

是的。匿名類型的匿名成員。當你糾正它時,請平息我。 – Deduplicator 2014-12-03 17:58:14