类/结构成员是否总是按照声明的顺序在内存中创建?

2021-12-21 00:00:00 memory c++ memory-alignment

这是一个由 Rob Walker 的回答 此处.

This is a question that was sparked by Rob Walker's answer here.

假设我像这样声明一个类/结构:

Suppose I declare a class/struct like so:

struct
{ 
    char A;
    int B;
    char C;
    int D;
};

假设这些成员将在内存中完全按照这个顺序声明是否安全,或者这是一个依赖于编译器的东西?我这么问是因为我一直认为编译器可以对它们做任何想做的事情.

Is it safe to assume that these members will be declared in exactly that order in memory, or is this a compiler dependent thing? I'm asking because I had always assumed that the compiler can do whatever it wants with them.

这就引出了我的下一个问题.如果上面的例子导致内存对齐问题,为什么编译器不能隐式地把它变成这样的:

This leads into my next question. If the above example causes memory alignment issues, why can the compiler not just turn that into something like this implicitly:

struct
{ 
    char A;
    char C;
    int B;
    int D;
};

(我主要询问 C++,但我也有兴趣听到 C 的答案)

(I'm primarily asking about C++, but I'd be interested to hear the C answer as well)

  • 为什么 GCC 不优化结构?

推荐答案

C99 §6.7.2.1 第 13 条规定:

C99 §6.7.2.1 clause 13 states:

在结构对象中,非位域成员和单元哪些位域驻留有地址增加的顺序它们被声明.

Within a structure object, the non-bit-?eld members and the units in which bit-?elds reside have addresses that increase in the order in which they are declared.

并继续说更多关于填充和地址的内容.C89 等效部分是 §6.5.2.1.

and goes on to say a bit more about padding and addresses. The C89 equivalent section is §6.5.2.1.

C++ 有点复杂.在 1998 和 2003 标准中,有 §9.2 第 12 条(C++11 中的第 15 条):

C++ is a bit more complicated. In the 1998 and 2003 standards, there is §9.2 clause 12 (clause 15 in C++11):

a 的非静态数据成员(非联合)类声明没有干预访问说明符是分配,以便后来的成员有一个类中的更高地址目的.分配顺序非静态数据成员由一个分隔未指定访问说明符(11.1).实施调整要求可能会导致两个相邻的不分配成员紧随其后;所以可能管理空间要求虚函数 (10.3) 和虚函数基类 (10.1).

Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).

相关文章