2010-12-14 98 views
5

一行代碼勝過千言萬語:)這裏是我的問題:C++內存對齊問題

/* Platform specific 16-byte alignment macro switch. 
    On Visual C++ it would substitute __declspec(align(16)). 
    On GCC it substitutes __attribute__((aligned (16))). 
*/ 
#define ALIGN_16 ... 

struct ALIGN_16 A {...}; 

A* ptr = new A; 
A* ptr2 = new A[20]; 

assert(size_t(ptr) % 16 == 0); 

for (int i=0; i<20; ++i) 
    assert(size_t(ptr2+i) % 16 == 0); 

assert(sizeof(A) % 16 == 0); 

我能想到的所有斷言通過與SSE支持的平臺?謝謝。

編輯。部分答案。我用VS2008,GCC和ICC做了一些測試。 MS編譯器確實對齊ptrptr2,但是GCC和ICC未能對齊ptr2

+0

爲什麼20的陣列如? – John 2010-12-15 00:03:08

+0

只是我的頭。如果陣列中的每個元素都對齊,我就會徘徊。 – watson1180 2010-12-15 00:22:49

+2

正確分配的數組的元素由標準保證爲所討論的類型正確對齊。然而,這種對齊是一個實現細節,理論上可能是一個字節(即壓縮對齊)。 – 2010-12-15 00:30:01

回答

4

Is there any guarantee of alignment of address return by C++'s new operation?

換句話說,你可以使用標準來證明你的假設,它應該工作,但在實踐中,它可能會在你的臉上炸燬。

Visual C++ 6沒有對齊doubles正確地通過new分配,所以你去了。

+0

那麼新編譯器呢? GCC 4.xx和VS 2008? – watson1180 2010-12-15 01:09:52

+1

我不知道任何編譯器提供16個字節與'new'或'malloc'對齊,這意味着在實踐中,斷言將失敗。 – jalf 2010-12-15 08:43:43

+0

@jalf,是的,這就是我的想法。我認爲它是用C++ 0x「支持」的,但考慮到HeapAlloc間接保證了8個字節(因爲Windows數據結構的缺省打包選項是8字節對齊),我懷疑這種情況很快就會發生。 – MSN 2010-12-15 23:45:08

1

的C++ 0x提供了一種新的構建體(在[meta.type.synop]20.7.6.6其它變換):

std::aligned_storage<Length, Alignment> 

這是保證被始終正確,只要對準我記得。

第二個參數是可選的,默認爲可能的最嚴格的要求(所以它總是安全的,而不是精確的,但如果你願意嘗試,你可以更緊湊地打包你的類型)。

除了bugs,編譯器必然會遵守要求。如果您沒有C++ 0x,則可以在tr1名稱空間或Boost中找到。

你是誰可以測試您的特定編譯器接受此請求:)唯一一個

注:gcc-4.3.2,它是這樣實現的:

template<std::size_t _Len, std::size_t _Align = /**/> 
struct aligned_storage 
{ 
    union type 
    { 
    unsigned char __data[_Len]; 
    struct __attribute__((__aligned__((_Align)))) { } __align; 
    }; 
}; 
+0

儘管對象分配了「new」,但通常不會遵守特定的對齊要求。 (它通常只給你8字節對齊的內存,這對於大多數用途來說已經足夠了) – jalf 2010-12-15 08:44:42

+0

@jalf:但標準要求'new'返回一段適當對齊的內存(從3.7.4.1 [basic.std.dynamic .allocation] $ 2),除非我不懂*,因此它可以轉換爲任何具有基本對齊要求(3.11)*和3.11 [基本對齊要求的完整對象類型的指針。對齊] $ 2 *基本對齊由對齊表示,小於或等於實現在所有上下文中支持的最大對齊,這等於alignof(std :: max_align_t)(18.2)。* – 2010-12-15 09:01:27

+0

...因此,我會說如果'new'只返回8字節對齊的值並且'std :: max_align_t'優於8,那麼實現是不符合的。 – 2010-12-15 09:01:58