为什么 char 数组的 alignof 总是 1?

Why is alignof of a char array always 1?

我正在阅读一些关于 C++ 对齐的内容,但我不确定为什么仅包含 char 数组成员的 class 的对齐不是数组的 sizeof,但结果总是1。例如

#include <iostream>

struct Foo{char m_[16];}; // shouldn't this have a 16 byte alignment?!

int main()
{
    std::cout << sizeof(Foo) << " " << alignof(Foo);
}

Live on Coliru

在上面的代码中很明显sizeof(Foo)是16,但是它的对齐是1,看代码的输出。

为什么在这种情况下 alignof(Foo) 是 1? 请注意,如果我将 char m_[16]; 替换为 int m_; 等基本类型,那么 alignof(Foo) 就会变成我所期望的,即 sizeof(int)(在我的机器上是 4)。

如果我简单地声明一个数组 char arr[16];,也会发生同样的情况,那么 alignof(arr) 将为 1。

注:数据对齐在this article中有详细说明。如果您想了解该术语的一般含义以及为什么它是一个重要问题,请阅读这篇文章。

对齐在 C++ 中定义为实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数 [6.11.1] Alignment

此外对齐必须是 2 的非负整数幂 [6.11.4] Alignment

当我们计算结构的对齐方式时,我们必须考虑另一个规则 [6.11.5] Alignment:

Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.

虽然没有直接说明,但这些规则暗示结构对齐必须至少与其最严格对齐的成员的对齐一样严格。它可以更大,但不一定是,通常也不是。

因此,当确定 OP 示例中结构的对齐方式时,结构的对齐方式必须不小于其唯一成员类型的对齐方式 char[16]。然后通过 8.3.6 [expr.alignof]:

When alignof is applied to a reference type, the result is the alignment of the referenced type. When alignof is applied to an array type, the result is the alignment of the element type.

alignof(char[16]) 等于 alignof(char) 通常是 1 因为 [6.11.6] Alignment:

(...) narrow character types shall have the weakest alignment requirement.

在这个例子中:

struct Foo
{
    char c[16];
    double d;
};

doublechar 更严格对齐,所以 alignof(Foo) 等于 alignof(double).