gcc / clang размещает поля производной структуры в отступах базовой структуры [duplicate]

На этот вопрос уже есть ответ:

Стандартная компоновка и обивка хвоста 5 ответов

Меня смущает то, как gcc и clang выстраивают структуры, когда задействованы как padding, так и наследование. Вот пример программы:

#include <string.h>
#include <stdio.h>

struct A
{
    void* m_a;
};

struct B: A
{
    void* m_b1;
    char m_b2;
};

struct B2
{
    void* m_a;
    void* m_b1;
    char m_b2;
};

struct C: B
{
    short m_c;
};

struct C2: B2
{
    short m_c;
};

int main ()
{
    C c;
    memset (&c, 0, sizeof (C));
    memset ((B*) &c, -1, sizeof (B));

    printf (
        "c.m_c = %d; sizeof (A) = %d sizeof (B) = %d sizeof (C) = %d\n", 
        c.m_c, sizeof (A), sizeof (B), sizeof (C)
        );

    C2 c2;
    memset (&c2, 0, sizeof (C2));
    memset ((B2*) &c2, -1, sizeof (B2));

    printf (
        "c2.m_c = %d; sizeof (A) = %d sizeof (B2) = %d sizeof (C2) = %d\n", 
        c2.m_c, sizeof (A), sizeof (B2), sizeof (C2)
        );

    return 0;
}

Выход

$ ./a.out
c.m_c = -1; sizeof (A) = 8 sizeof (B) = 24 sizeof (C) = 24
c2.m_c = 0; sizeof (A) = 8 sizeof (B2) = 24 sizeof (C2) = 32

Структуры C1 и C2 расположены по-разному. В C1 m_c размещается в отступе структуры B1 и поэтому перезаписывается 2-м memset (); с C2 этого не происходит.

Используются компиляторы:

$ clang --version
Ubuntu clang version 3.3-16ubuntu1 (branches/release_33) (based on LLVM 3.3)
Target: x86_64-pc-linux-gnu
Thread model: posix

$ c++ --version
c++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

То же самое происходит с опцией -m32 (очевидно, что размеры выходных данных будут другими).

В обеих версиях компилятора Microsoft Visual Studio 2010 C ++ для x86 и x86_64 такой проблемы нет (т. Е. Они одинаково выкладывают структуры С1 и С2)

Если это не ошибка, и она задумана, то мои вопросы:

Каковы точные правила для выделения или не выделения полей производной структуры в отступах (например, почему это не происходит с C2?) есть ли способ переопределить это поведение с помощью переключателей / атрибутов (т.е. выложить так же, как MSVC)?

Заранее спасибо

Владимир

Ответы на вопрос(4)

Ваш ответ на вопрос