1

这个问题与如何确保成员是 4 字节对齐的?

例子:

struct Aligned
{
    char c;
    __attribute__((__aligned__(4))) int32_t member;
}

struct Test
{
    char    c;
    Aligned s;//is s.member 4 bytes aligned?
}


void f1()
{
    char    c1;
    Aligned s;//is s.member 4 bytes aligned?
    char    c2;
}

void f2()
{
    Aligned* s = new Aligned();//is s.member 4 bytes aligned?
}

您能否解释一下“成员”是否在所有情况下都是 4 个字节对齐的,如果是,它是如何工作的?

编辑:我忘记了 Aligned 派生自其他结构的情况:

struct Aligned : public SomeVariableSizeStruct
{
    char c;
    __attribute__((__aligned__(4))) int32_t member;
}

第二次编辑:我的问题是:结构的第一个成员总是4字节对齐吗?因为在这里介绍的所有情况下,第一个变量地址可能不是 4 字节对齐的,并且 3 字节填充不能保证“成员”是 4 字节对齐的

4

4 回答 4

4

是的,它有效。需要编译器才能使其工作。

每种类型都有编译器必须遵守的对齐方式。您已指定一个特定对象应使用 4 字节对齐,但所有其他对象 a char、 an int、 astd::string和其他任何对象有其自己的对齐要求。

所以编译器习惯于处理这个问题。

为了确定 所需的对齐Aligned,编译器基本上会遍历其所有成员(以及它的基类)以找到需要最严格对齐的那个。然后这Aligned也成为所需的对齐。

在这种情况下,最对齐的成员是member,它需要 4 字节对齐。所以Aligned需要4字节对齐。

是的,无论您是Aligned在堆栈上创建一个作为函数局部变量,还是作为另一个类成员,还是在堆上使用new.

于 2012-08-16T08:48:31.833 回答
3

它是如何工作的?

当您定义 astruct时,您定义了在处理为 this 时如何使用内存struct。这意味着当你定义struct如下

struct Aligned
{
    char c;
    __attribute__((__aligned__(4))) int32_t member;
}

编译器定义了如何处理与 this 对应的内存struct Aligned。例如,编译器将使用具有以下布局的内存*:

bytes: |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
usage: |  c  |  X  |  X  |  X  |        member         |

X 表示未使用这些字节。这称为填充

*:请注意,这适用于 x86 架构,并且可能在其他架构上有所不同。但是不使用某些字节的事实是相同的。

于 2012-08-16T08:44:03.530 回答
1

您能否解释一下“成员”是否在所有情况下都是 4 个字节对齐的,如果是,它是如何工作的?

是的。例外情况是,如果您告诉编译器打包您的结构。

这个怎么运作?编译器无形地对齐所有内容。它在成员之间添加填充/空间。这是 ABI 和生成程序集的要求。当然,程序员仍然能够使用非自然对齐的数据。

作为一种优化,编译器可能会重新排序您的成员——在某些情况下:C++ 编译器可以重新排序结构中的元素吗?

于 2012-08-16T08:40:49.963 回答
0

它可以工作,因为编译器必须让它工作。编译器将在内部具有类型描述,Aligned其中包括其名称和 等属性,以及sizeof对齐限制。

于 2012-08-16T08:40:41.637 回答