我仍然从他们的简短的讨论中看不懂,怎么可能呢?
解决方法
在C 03中,有语言使之成为可能,9.2 [class.mem] / 12(强调我的):
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).
所以给出这个定义:
class Foo { char a; //8 bits // a must come before b,so 3 bytes of padding have to go here to satisfy alignment int b; //32 bits char c; //8 bits // 24 bits of padding required to make Foo a multiple of sizeof(int) };
在具有32位(int)对齐的系统上,编译器不允许在b之前重新排序c,强制在a和b之间以及c之后插入附加填充填充到对象的结尾(使sizeof( Foo)== 12).但是,为此:
class Foo { char a; public: int b; public: char c; };
a和(b和c)由访问说明符分隔,因此编译器可以自由地执行这样的重新排序
memory-layout Foo { char a; // 8 bits char c; // 8 bits // 16 bits of padding int b; // 32 bits };
sizeof(Foo)== 8.
在C11中,语言略有变化. N3485 9.2 [class.mem] / 13说(强调我的):
Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (Clause 11). 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).
这意味着在C 11中,在上面的例子中(由3个公开分隔),编译器仍然不允许执行重新排序.它必须是这样的东西
class Foo { char a; public: int b; protected: char c; };
,其中a,b和c具有不同的访问控制.
请注意,根据C 11规则,给出一个定义如下:
class Foo { char a; public: int b; protected: char c; public: int d; };
编译器必须将d放在b之后,即使它们被访问说明符分隔.
(也就是说,我不知道实际上利用了两种标准提供的纬度)