Is size of the object affected by type of access-specifier and type of inheritance?

萝らか妹 提交于 2019-12-23 07:26:23

问题


While answering one of the question, there was a discussion thread below my answer. Which suggests that depending on the access specifier (or may be the type of inheritance) private/protected/public the sizeof the class object may vary!

I still don't understand from their brief discussion, how is that possible ?


回答1:


Note new language for C++11 below

In C++03, there is language that makes this possible, 9.2 [class.mem]/12 (emphasis mine):

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

So given this definition:

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)
};

on a system with 32 bit (int) alignment, the compiler is not allowed to reorder c to come before b, forcing the insertion of additional padding padding in between a and b, and after c to the end of the object (making sizeof(Foo) == 12). However, for this:

class Foo
{
    char a;
public:
    int b;
public:
    char c;
};

a and (b and c) are separated by an access specifier, so the compiler is free to perform such reordering, making

memory-layout Foo
{
    char a; // 8 bits
    char c; // 8 bits
    // 16 bits of padding
    int b; // 32 bits
};

sizeof(Foo) == 8.

In C++11, the language changes slightly. N3485 9.2 [class.mem]/13 says (emphasis mine):

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

This means that in C++11, in the above example (separated by 3 publics), the compiler is still not allowed to perform the reordering. It would have to be something like

class Foo
{
    char a;
public:
    int b;
protected:
    char c;
};

, which places a, b, and c with different access control.

Note that under the C++11 rules, given a definition like:

class Foo
{
    char a;
public:
    int b;
protected:
    char c;
public:
    int d;
};

the compiler must put d after b, even though they are separated by access specifiers.


(That said, I'm not aware of any implementation that actually takes advantage of the latitude offered by either standard)



来源:https://stackoverflow.com/questions/6577906/is-size-of-the-object-affected-by-type-of-access-specifier-and-type-of-inheritan

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!