2010-12-14 90 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