【问题标题】:Alignment guarantees of static char array静态字符数组的对齐保证
【发布时间】:2012-06-26 19:29:32
【问题描述】:

我想知道char 的静态分配数组的对齐保证。查看其他 SO 问题,我发现了一些有关动态分配的 char 数组。

对于静态分配的char 数组,它们是否对齐以便我可以将新的任何类型放入其中(只要它足够大)?还是这只适用于动态分配的?

char buff[sizeof(T)];
T * pT = (T*) buff;
new(pT) T(); // well defined?
...
pT->~T();

如果没有,我该如何解决这个问题?

【问题讨论】:

  • 我相信 C++11 可以保证这一点,而 C++03 则不能。我会让其他人发布带有标准引用的实际答案。
  • @K-ballo:我认为 C++11 不能保证这一点。它为此添加了alignas
  • @Nawaz:这是我对 3.11/6 [basic.align] 的理解,你怎么看?我弄错了吗?
  • @K-ballo:我很确定你弄错了。 3.11/6 表示 char 类型具有最弱的对齐方式,而 3.11/5 表示更严格的对齐方式(具有较大的对齐值)满足较弱的对齐方式(具有较小的对齐值),而不是相反。归结为,只要您注意对齐,您就可以将 char 类型用于对齐的内存区域。按照 3.11/6 的注释对 7.6.2(对齐说明符)的引用来查看一种方法。另一种方法是过度分配 char 数组,并在数组内以适当的对齐方式使用偏移指针。

标签: c++ memory-alignment


【解决方案1】:

在 C++11 中,正确的做法是:

char alignas(T) buff[sizeof(T)]; //Notice 'alignas' as
T * pT = (T*) buff;
new(pT) T(); // well defined!

注意alignas的使用。

如果T 是模板参数,那么最好使用std::alignment_of 类模板作为:

char alignas(std::alignment_of<T>::value) buff[sizeof(T)]; 

还要注意alignas 的参数可以是正整数值类型。所以这两个是等价的:

char alignas(T)          buff[sizeof(T)];
char alignas(alignof(T))  buff[sizeof(T)]; //same as above

第二个使用alignof,它返回一个std::size_t类型的整数值。

【讨论】:

  • C++,那该是多么美妙的语言啊! :P
  • @Nawaz:K-ballo(幽默地)指的是您的“In C++11”开场白。
  • @DavidHammen:哎呀...我没注意到。
  • @Nawaz,我不认为 alignas(T) 与 alignas(sizeof(T)) 相同。以结构体为例,对齐是最严格对齐的成员之一,它小于任何具有多个成员的结构体的大小。
  • @AProgrammer:这是一个错字。我的意思是alignas(alignof(T)) 不是alignas(sizeof(T))
【解决方案2】:

如果要保证静态char数组的对齐,可以使用union技巧。

union
{
    char buff[sizeof(T)];
    uint64_t dummy;
};

这里将保证联合中最大元素的对齐。当然,你应该在一个漂亮的课堂上把这些讨厌的东西包起来。

编辑:更好的答案:

当然,在 C++11 中使用 boost::aligned_storagealignas 会更好。

【讨论】:

    【解决方案3】:

    没有。静态分配的数组与sizeof(element_type) 字节对齐——对于 char 它是 1 个字节,这基本上保证了不对齐。

    【讨论】:

    • 同样的规则是否适用于二维数组,比如char a[M][N]
    • @MichałGórny 我相信是这样,因为它们实际上只是一维的。
    猜你喜欢
    • 1970-01-01
    • 2019-10-19
    • 2013-09-09
    • 2011-04-29
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多