对齐栈(C ++)上的数据 [英] Aligning data on the stack (C++)

查看:126
本文介绍了对齐栈(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆