如果已知结构成员的对齐方式,是否可以找到结构类型的对齐方式?
Eg. for:
struct S
{
a_t a;
b_t b;
c_t c[];
};
S = max(alignment_of(a),alignment_of(b),alignment_of(c)) 的对齐方式是?
在互联网上搜索我发现“对于结构化类型,其任何元素的最大对齐要求决定了结构的对齐方式”(在每个程序员都应该了解的内存知识 http://people.redhat.com/drepper/cpumemory.pdf)但我在标准中找不到任何类似的内容(更准确地说是最新草案)。
Edited:非常感谢所有的答案,特别是罗伯特·甘布尔(Robert Gamble),他为最初的问题和其他贡献者提供了非常好的答案。
简而言之:
为了确保结构成员的对齐要求,结构的对齐必须至少与其最严格成员的对齐一样严格。
至于确定结构的对齐,提出了一些选项,经过一些研究,我发现:
- c++ std::tr1::alignment_of
- 尚未标准,但接近(技术报告 1),应该在 C++0x 中
- the following restrictions are present in the latest draft: Precondition:T shall be a complete type, a reference type, or an array of
unknown bound, but shall not be a function type or (possibly
cv-qualified) void.
- 这意味着我提出的使用 C99 灵活数组的用例将无法工作(这并不奇怪,因为灵活数组不是标准 C++)
- 在最新的 C++ 草案中,它是根据新关键字 -alignas 定义的(这具有相同的完整类型要求)
- 在我看来,如果c++标准支持C99灵活数组,则可以放宽要求(结构与灵活数组的对齐不应根据数组元素的数量而改变)
- c++ boost::alignment_of
- 主要是tr1的替代品
- 似乎专门用于 void 并在这种情况下返回 0 (这在 c++ 草案中是禁止的)
- 开发人员注意:严格来说,您应该只依赖 ALIGNOF(T) 的值作为 T 的真实对齐方式的倍数,尽管实际上它确实在我们所知的所有情况下计算出正确的值。
- 我不知道这是否适用于灵活的数组,它应该(一般情况下可能不起作用,这解析为我的平台上的编译器固有的,所以我不知道它在一般情况下会如何表现)
- Andrew Top presented a simple template solution for calculating the alignment in the answers
- 这似乎非常接近 boost 正在做的事情(如果据我所知,boost 会另外返回对象大小作为对齐方式,如果它小于计算的对齐方式),所以可能同样的通知适用
- 这适用于灵活的数组
- use Windbg.exe to find out the alignment of a symbol
- using offsetof on the anonymous structure containing the type
- 查看答案,不可靠,不能用 c++ 非 POD 移植
- compiler intrinsics, eg. MSVC __alignof
- 适用于灵活的阵列
- alignof 关键字位于最新的 C++ 草案中
如果我们想使用“标准”解决方案,我们仅限于 std::tr1::alignment_of,但是如果将 c++ 代码与 c99 的灵活数组混合在一起,那么这将不起作用。
据我所知,只有 1 个解决方案 - 使用旧的 struct hack:
struct S
{
a_t a;
b_t b;
c_t c[1]; // "has" more than 1 member, strictly speaking this is undefined behavior in both c and c++ when used this way
};
在这种情况下(以及所有其他情况),不同的 C 和 C++ 标准以及它们日益增长的差异是不幸的。
另一个有趣的问题是(如果我们无法以可移植的方式找出结构的对齐方式)最严格的对齐要求是什么。我可以找到几个解决方案:
- boost(内部)使用各种类型的联合并在其上使用 boost::alignment_of
- the latest c++ draft contains std::aligned_storage
- The value of default-alignment shall be the most stringent alignment requirement for any C++ object type whose size is no greater than Len
- so the
std::alignment_of< std::aligned_storage<BigEnoughNumber>>::value
应该给我们最大的对齐
- 仅草案,尚未标准(如果有的话),
tr1::aligned_storage
没有这个属性
任何对此的想法也将不胜感激。
我暂时取消选中已接受的答案,以获得更多关于新子问题的可见性和输入