这个问题特定于MSVC编译器(特别是2008),但我也对非编译器特定的答案感兴趣.
我试图弄清楚如何在堆栈上对齐char缓冲区,基于某些任意类型的对齐.理想情况下,代码将为:
__declspec( align( __alignof(MyType) ) ) char buffer[16*sizeof(MyType)];
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用
错误C2059:语法错误:'__ builtin_alignof'
编译器只是不喜欢嵌套语句.
我唯一的另一个想法是这样做:
char buffer[16*sizeof(MyType)+__alignof(MyType)-1];
char * alignedBuffer = (char*)((((unsigned long)buffer) + __alignof(MyType)-1)&~(__alignof(MyType)-1));
Run Code Online (Sandbox Code Playgroud)
有谁知道更好的方式?似乎declspec的东西应该工作,我只是语法错误或什么?
谢谢阅读 :)
您可以std::aligned_storage
与std::alignment_of
其他人一起使用.
#include <type_traits>
template <class T, int N>
struct AlignedStorage
{
typename std::aligned_storage<sizeof(T) * N, std::alignment_of<T>::value>::type data;
};
AlignedStorage<int, 16> myValue;
Run Code Online (Sandbox Code Playgroud)
MSVC 2008及更高版本支持此功能.如果需要移植到其他非C++ 11个编译器可以使用std::tr1::aligned_storage
与std::tr1::alignment_of
和<tr1/type_traits>
头部.
在上面的代码中,AlignedStorage<T>::data
将是POD类型(MSVC和GCC中的char []数组),其具有T和大小T*N的适当对齐.
更新
检查罗伯特·奈特的答案!使用 C++11 但比这个干净得多......
原答案
这个令人讨厌的黑客怎么样:
namespace priv {
#define PRIVATE_STATICMEM(_A_) \
template <size_t size> \
struct StaticMem<size,_A_> { \
__declspec(align(_A_)) char data[size]; \
void *operator new(size_t parSize) { \
return _aligned_malloc(parSize,_A_); \
} \
void operator delete(void *ptr) { \
return _aligned_free(ptr); \
} \
};
template <size_t size, size_t align> struct StaticMem {};
template <size_t size> struct StaticMem<size,1> {char data[size];};
PRIVATE_STATICMEM(2)
PRIVATE_STATICMEM(4)
PRIVATE_STATICMEM(8)
PRIVATE_STATICMEM(16)
PRIVATE_STATICMEM(32)
PRIVATE_STATICMEM(64)
PRIVATE_STATICMEM(128)
PRIVATE_STATICMEM(256)
PRIVATE_STATICMEM(512)
PRIVATE_STATICMEM(1024)
PRIVATE_STATICMEM(2048)
PRIVATE_STATICMEM(4096)
PRIVATE_STATICMEM(8192)
}
template <typename T, size_t size> struct StaticMem : public priv::StaticMem<sizeof(T)*size,__alignof(T)> {
T *unhack() {return (T*)this;}
T &unhack(size_t idx) {return *(T*)(data+idx*sizeof(T));}
const T &unhack() const {return *(const T*)this;}
const T &unhack(size_t idx) const {return *(const T*)(data+idx*sizeof(T));}
StaticMem() {}
StaticMem(const T &init) {unhack()=init;}
};
Run Code Online (Sandbox Code Playgroud)
看起来很可怕,但你只需要一次(最好是在一些隐藏得很好的头文件中:))。然后您可以通过以下方式使用它:
StaticMem<T,N> array; //allocate an uninitialized array of size N for type T
array.data //this is a raw char array
array.unhack() //this is a reference to first T object in the array
array.unhack(5) //reference to 5th T object in the array
Run Code Online (Sandbox Code Playgroud)
StaticMem<T,N> array;
可以出现在代码中,但也可以作为某个更大类的成员(这就是我使用此技巧的方式),并且在堆上分配时也应该表现正确。
错误修复:
示例的第 6 行:char data[_A_]
更正为char data[size]
归档时间: |
|
查看次数: |
3659 次 |
最近记录: |