2015-10-08 92 views
0

作爲工會或結構的全局變量的默認對齊方式是什麼。他們是否保證字對齊?特別是使用GCC和SDCC時。C中的默認聯合和結構對齊?

在代碼中,函數f()是否安全,還是會導致未對齊訪問? 16位和32位平臺有區別嗎?

#define ADDR_SIZE 8 

typedef union { 
    unsigned char u8[ADDR_SIZE]; 
} addr_t; 

addr_t global_address; 

void f(void) { 
    uint32_t x = *((uint32_t *)&global_address) + *((uint32_t *)&global_address + 1); 
} 
+1

使用編譯指示確保包結構。請參見[這裏](https://gcc.gnu.org/onlinedocs/gcc/Structure-Packing-Pragmas.html) – LPs

+0

術語「Word」沒有定義的大小/寬度,所以在這裏沒用。該標準沒有(不能)強加任何對齊。 – Olaf

+0

Pragma不是一種選擇,因爲代碼必須根據項目規則是「獨立於編譯器」。 – kfx

回答

1

除非你指定使用例如__attribute__((aligned(4)))對齊要求,你不能保證工會要正確對齊。

隨着使用char喜歡這裏小心全局變量安排:

... 
#define ADDR_SIZE 8 

typedef union { 
    unsigned char u8[ADDR_SIZE]; 
} addr_t; 

addr_t global_address1; 
char padd1; 
addr_t global_address2; 
addr_t global_address3; 
... 

您可以see這裏的奇數地址:

0x804971d * &global_address1 
0x8049714 
0x8049715 * &global_address2 
0x804970c 

試圖在某些架構具有嚴格的對準要求訪問這些地址將導致一些未對齊的訪問異常並暫停程序。其他能夠以性能成本處理不對齊訪問的體系結構將需要至少兩個存儲器讀取週期,以完成多個CPU週期。

1

什麼是作爲工會或結構的全局變量的默認對齊方式。

這取決於工會成員。

它們是否保證字對齊?

否(假設字是4字節)。對齊要求很複雜。 Althoug它們很少大於sizeof(int),它們可能會因每種類型而不同。


在C11,通過包括max_align_t對象,工會將被按照需要的任何類型的對準。

max_align_t這是一種對象類型,其對齊方式與實現在所有上下文中支持的一樣大; C11§7.192

#include <stddef.h> 

typedef union { 
    max_align_t dummy; 
    unsigned char u8[ADDR_SIZE]; 
} addr_t; 

@Jens Gustedt有大約走樣好點。只需從工會內部訪問uint32_t即可。留意endian問題。

typedef union { 
    unsigned char u8[ADDR_SIZE]; 
    uint32_t u32[ADDR_SIZE/sizeof(uint32_t)]; 
} addr_t;