2009-08-14 73 views
0

好的,請允許我重新提出問題,因爲沒有答案得到我真正感興趣的內容(道歉,如果像這樣的問題的全面編輯是一種人造主義)。用於確定C/C++結構中元素對齊的算法

的幾點:

  • 這是一個不同的編譯器一個比我測試的離線分析,所以SIZEOF()或類似的將不是我在做什麼工作。
  • 我知道它是實現定義的,但我碰巧知道下面我感興趣的實現。

讓我們做一個叫包功能,這需要作爲輸入一個整數,稱爲校準和整數的元組,稱爲元素。它輸出另一個整數,稱爲大小。

功能的工作原理如下:

int pack (int alignment, int[] elements) 
{ 
    total_size = 0; 

    foreach(element in elements) 
    { 
    while(total_size % min(alignment, element) != 0) { ++total_size; } 
    total_size += element; 
    } 

    while(total_size % packing != 0) { ++total_size; } 

    return total_size; 
} 

我想我要問的是「這是什麼函數的反函數?」,但我不知道是否反轉是正確的term--我不記得曾經用多輸入來處理函數的反轉,所以我可能只是使用一個不適用的術語。

像我想要的東西(排序)存在;這裏我提供了一個函數的僞代碼,我們將其稱爲determine_align。這個函數有點幼稚,因爲它只是一次又一次地用不同的輸入來調用打包,直到它得到它期望的(或失敗的)答案。

int determine_align(int total_size, int[] elements) 
{ 
    for(packing = 1,2,4,...,64) // expected answers. 
    { 
    size_at_cur_packing = pack(packing, elements); 

    if(actual_size == size_at_cur_packing) 
    { 
     return packing; 
    } 
    } 

    return unknown; 
} 

所以問題是,有更好的執行判定_align嗎?

謝謝,

回答

3

我讓編譯器爲我做對齊。

在GCC,

typedef struct _foo 
{ 
    u8 v1 __attribute__((aligned(4))); 
    u16 v2 __attribute__((aligned(4))); 
    u32 v3 __attribute__((aligned(8))); 
    u8 v1 __attribute__((aligned(4))); 
} foo; 

編輯:注意的sizeof(富)將返回正確的值,包括任何填充。

Edit2:和offsetof(foo,v2)也適用。給定這兩個函數/宏,你可以找出你需要知道的內存中結構佈局的一切。

0

您需要墊基礎上,下一個字段的位置,然後墊基礎上,最大對齊的最後一個元素你在結構中看出。請注意,字段的實際對齊方式是其自然對齊和該結構的打包的最小值。也就是說,如果你有包裝,4個字節的結構,雙將對齊爲4個字節,即使它的自然對齊是8

你可以使內環與total_size+= total_size % min(packing, element.size);你可以更快,如果packing進一步優化它, element.size是兩個冪。

7

在C/C++結構成員的對齊是完全實現定義的。這裏有幾個保證,但我不明白他們會如何幫助你。

因此,沒有通用的方法做你想要什麼。在特定實現的上下文中,您應該參考涵蓋此實現的文檔(如果它被覆蓋)。

5

當選擇怎麼收拾成員爲struct實現不必須遵循的那種方案,你在你的算法描述,雖然這是一個常見的一種。 (即對齊的最小尺寸的類型和優選的機器對齊尺寸。)

儘管如此,您不必比較struct的整體尺寸以確定已應用於單個struct成員的填充。標準宏offsetof將給出任何單個結構成員的起始struct的字節偏移量。

0

如果問題只是要保證特定的對齊,那很容易。對於特定的排列= 2^N:

void* p = malloc(sizeof(_foo) + alignment -1); 
p = (void*) (((char*)(p) + alignment - 1) & ~alignment); 

我忽略保存到原來的對從malloc返回。如果您打算釋放該內存,則需要將該指針保存在某處。

2

我真的不知道你想要做什麼,我可能完全誤解你在找什麼,但如果你想簡單地確定一個結構的對齊要求是什麼,以下宏可能會有所幫助:

#define ALIGNMENT_OF(t) offsetof(struct { char x; t test; }, test) 

要確定您的foo結構的調整,你可以這樣做:

ALIGNMENT_OF(foo); 

如果這不是你最終特林做,有可能這個宏可以幫助你使用任何算法確實想出來。

0

我不確定你想在這裏實現什麼。正如Pavel Minaev所說,對齊是由編譯器處理的,而編譯器又受平臺的應用程序二進制接口約束,用於數據的訪問,這些數據可由不同編譯器編譯的代碼訪問。以下論文在需要實現調用約定的編譯器上下文中討論該問題:

Christian Lindig和Norman Ramsey。 堆棧幀的聲明組成。在Evelyn Duesterwald,編輯,Proc。第14屆國際編譯器製造會議,Springer,LNCS 2985,2004。