gcc / clang Felder einer abgeleiteten Struktur in der Rückauffüllung der Basisstruktur auslegen [duplizieren]

Diese Frage hat hier bereits eine Antwort:

Standard-Layout und Heckpolsterung 5 Antworten

Ich bin verwirrt darüber, wie gcc und clang Strukturen auslegen, wenn sowohl das Auffüllen als auch die Vererbung beteiligt sind. Hier ist ein Beispielprogramm:

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

Ausgabe

$ ./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

Structs C1 und C2 sind unterschiedlich angeordnet. In C1 wird m_c im Back-Padding von struct B1 zugewiesen und wird daher vom 2nd memset () überschrieben; mit C2 passiert das nicht.

Compiler verwendet:

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

Das gleiche passiert mit der Option -m32 (die Größen in der Ausgabe sind natürlich unterschiedlich).

Beide x86- und x86_64-Versionen des Microsoft Visual Studio 2010 C ++ - Compilers haben dieses Problem nicht (d. H. Sie ordnen die Strukturen С1 und C2 identisch an)

Wenn es kein Fehler ist und beabsichtigt ist, dann sind meine Fragen:

Was sind die genauen Regeln für die Zuweisung oder Nichtzuweisung von Feldern einer abgeleiteten Struktur im Back-Padding (z. B. warum passiert das nicht mit C2?) Gibt es eine Möglichkeit, dieses Verhalten mit Schaltern / Attributen zu überschreiben (d. h. wie bei MSVC darzustellen)?

Danke im Voraus

Vladimir

Antworten auf die Frage(4)

Ihre Antwort auf die Frage