关于c ++:类/ struct成员总是按照它们被声明的顺序在内存中创建吗?

Do class/struct members always get created in memory in the order they were declared?

这是罗布·沃克的回答引发的一个问题。

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

1
2
3
4
5
6
7
struct
{
    char A;
    int B;
    char C;
    int D;
};

假设这些成员在内存中的声明顺序正好是这样的,或者这是一个依赖于编译器的东西,这样做安全吗?我问是因为我一直认为编译器可以用它们做任何它想做的事情。

这引出了我的下一个问题。如果上面的示例导致内存对齐问题,为什么编译器不能将其隐式地转换为类似这样的内容:

1
2
3
4
5
6
7
struct
{
    char A;
    char C;
    int B;
    int D;
};

(我主要是问C++,但我也很想听到C的答案)

相关主题

  • 为什么GCC不优化结构?

C99§6.7.2.1第13条规定:

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。

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

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).


数据成员按声明的顺序排列。编译器可以随意散布填充来排列它喜欢的内存对齐方式(并且您会发现许多编译器都有一个booatload对齐规范选项——如果混合了由不同程序编译的位,这很有用)。

另请参见gcc为什么不优化结构?.

看来C++的答案有些过时了。你每天都会学到一些东西。谢谢你,内曼扎。


基本上,您只能依赖于具有标准布局的类。严格来说,标准布局是一个C++ 0x的东西,但它实际上只是在规范现有的实践。


除了填充的对齐方式,没有任何结构优化允许任何编译器(我知道)的C或C++。我不能为C++类说话,因为它们可能完全是另一种野兽。

考虑您的程序正在与Windows上的系统/库代码接口,但您希望使用gcc。您必须验证gcc使用了相同的布局优化算法,以便在将所有结构发送到MS编译的代码之前正确打包它们。


我不能为C++说话,但是在C中,顺序保证在结构中声明的内存中的顺序相同。


当浏览右侧的相关主题时,我看到了这个问题。我认为在考虑这些问题时,这可能是一个有趣的角落案例(除非它比我意识到的更常见)。

要解释,如果您有一个C中的结构看起来像这样:

1
struct foo{};

和它在C ++中使用的子类(使用单独的编译单元):

1
2
extern"C" foo;
struct bar: public foo{};

那么,由于AIB提到的原因(即使是同一供应商的编译器之间),内存对齐也不一定是相同的。