对齐栈(C ++)上的数据 [英] Aligning data on the stack (C++)
问题描述
此问题是特定于MSVC编译器(特别是2008年),但我感兴趣的非编译具体答案了。
This question is specific to the MSVC compiler (specifically 2008), but I'm interested in non-compiler specific answers too.
我试图找出如何使一个字符缓冲区在堆栈上,基于某种任意类型的对齐方式。理想情况下,code应改为:
I'm trying to figure out how to align a char buffer on the stack, based on the alignment of some arbitrary type. Ideally the code would read:
__declspec( align( __alignof(MyType) ) ) char buffer[16*sizeof(MyType)];
不幸的是,这不工作
Unfortunately, this doesn't work
错误C2059:语法错误: __builtin_alignof
error C2059: syntax error : '__builtin_alignof'
编译器只是不喜欢那些语句。
The compiler just doesn't like the nested statements.
我唯一的想法就是要做到这一点:
My only other idea is to do this:
char buffer[16*sizeof(MyType)+__alignof(MyType)-1];
char * alignedBuffer = (char*)((((unsigned long)buffer) + __alignof(MyType)-1)&~(__alignof(MyType)-1));
有谁知道一个更好的办法吗?这似乎是declspec的事情应该工作,我只是有语法错误还是怎么了?
Does anyone know of a nicer way? It seems like the declspec thing should work, do I just have the syntax wrong or something?
感谢您阅读:)
推荐答案
更新
检查罗伯特骑士的回答!使用C ++ 11,但比这更清洁...
Check Robert Knight's answer! Uses C++11 but is much cleaner than this...
原来的答案
这个怎么样讨厌黑客:
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;}
};
看起来吓人,但你需要所有的只有一次(preferably一些隐藏的很好的头文件:))。然后,您可以通过以下方式使用它:
Looks scary, but you need all that only once (preferably in some well hidden header file :) ). Then you can use it in the following way:
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
StaticMem&LT; T,N&GT;数组;
可以出现在code,也可作为一些较大的类的成员(这是我如何使用这个hack),也应该正确的行为在堆中分配时
StaticMem<T,N> array;
can appear in the code, but also as a member of some bigger class (that's how I use this hack) and should also behave correctly when allocated on the heap.
修正错误:
本例中6号线: CHAR数据[_A _]
修正为字符数据【尺寸】
Line 6 of the example: char data[_A_]
corrected into char data[size]
这篇关于对齐栈(C ++)上的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!