2016-07-21 28 views
-1

Ich habe diese C++ Struktur:sizeof (struct) gibt einen KLEINEREN als erwarteten Wert zurück?

struct Packet 
{ 
    uint32 MessageCount; 
    uint32 Length; 
    uint32 FieldValue; 

    union PacketHeader 
    { 
     uint32 typeInfo; 
     struct MagicVersion 
     { 
      uint8 MagicNumber[3]; 
      uint8 Version; 
     }; 
    }; 

    Data * Payload(void) { return reinterpret_cast< Data * >(this + 1U); } 
    Data const * Payload(void) const { return reinterpret_cast< Data const * >(this + 1U); } 

    Packet * nextPacket(void) { return reinterpret_cast< Packet * >(this + 1U) + Length; } 
    Packet const * nextPacket(void) const { return reinterpret_cast< Packet const * >(this + 1U) + Length; } 
}; 

Dann sizeof(Packet) in MSVC++ liefert 12 statt 16, das ist das, was ich erwarte.

Das Seltsame ist natürlich, dass dies kleiner ist als der erwartete Wert. Wäre es größer gewesen, könnte das an Ausrichtungsproblemen liegen.

Was fehlt mir?

TIA

+0

Beachten Sie, dass Sie diese Union nicht verwenden sollten, um zwischen uint32_t und uint8_t []; das ist UB. – lorro

Antwort

10

Warum denken Sie, dass es größer sein sollte?

Es enthält 3 uint32 ohne virtuelle Methoden, das ist genau 12 Bytes.

Die Union zählt nicht, da es ein Typ ist, enthält es kein Mitglied dieses Typs.

Wenn Sie Ihre Klasse wollen eine einzelne Instanz der Union enthalten, die eine einzelne Instanz der Struktur enthält, sollten Sie schreiben:

struct Packet 
{ 
    uint32 MessageCount; 
    uint32 Length; 
    uint32 FieldValue; 

    union 
    { 
     uint32 typeInfo; 
     struct 
     { 
      uint8 MagicNumber[3]; 
      uint8 Version; 
     } /* MagicVersion */; 
    }; 
} /* PacketHeader */; 

Die Namen innerhalb /**/ optional sind, können Sie sie entweder angeben oder nicht. Wenn Sie dies tun, müssen Sie auf ihre Mitglieder mit dem Namen union/struct zugreifen, sonst haben Sie eine flache Struktur Packet.

+0

C++ unterstützt jedoch sowohl unbenannte als auch anonyme Verbindungen. Also, wenn er PacketHeader entfernt, sollte das funktionieren. – VladimirS

+0

Es tut. Wenn Sie den Namen 'PacketHeader' nach dem Schlüsselwort 'union' entfernen, wird' sizeof (Packet) '16 Byte lang sein. – Dutow

+0

, aber g ++ würde dann weinen, weil die benannte Struktur, die in einer namenlosen Vereinigung verschachtelt ist, nicht existieren kann. – nass