Unterschied zwischen sizeof (leere Struktur) und sizeof (Struktur mit leerem Array)?

Lesezeit: 3 Minuten

Benutzeravatar von duong_dajgja
duong_dajgja

Ich habe zwei Strukturen wie folgt definiert:

struct EmptyStruct{

};

struct StructEmptyArr{
    int arr[0];
};

int main(void){
    printf("sizeof(EmptyStruct) = %ld\n", sizeof(EmptyStruct));
    printf("sizeof(StructEmptyArr) = %ld\n", sizeof(StructEmptyArr));

    return 0;
}

Kompiliert mit gcc (g++) 4.8.4 auf Ubuntu 14.04, x64.

Ausgabe (sowohl für gcc als auch für g++):

sizeof(EmptyStruct) = 1
sizeof(StructEmptyArr) = 0

Ich kann verstehen, warum sizeof(EmptyStruct) ist gleich 1 kann aber nicht verstehen warum sizeof(StructEmptyArr) ist gleich 0. Warum gibt es Unterschiede zwischen zwei?

  • Letzteres ist keine gültige Struktur, daher erstellt der Compiler einen eigenen Wert, indem er der C++-Sprache Funktionen hinzufügt. Die Idee ist wahrscheinlich, dass sizeof(struct)+sizeof(array) einen Zeiger direkt hinter dem Array ergibt und (char*)structpointer+sizeof(struct) das erste Element des Arrays liefert.

    – Johannes Schaub – litb

    19. Juli 2017 um 15:19 Uhr


  • Bezogen auf: stackoverflow.com/questions/1626446/…, stackoverflow.com/questions/9722632/…

    – Jonny Schubert

    19. Juli 2017 um 15:24 Uhr


  • Interessant, weil ich das gerade mit gcc Version 6.3.0 gemacht habe und für beide eine Ausgabe von 0 bekommen habe.

    – mgey

    19. Juli 2017 um 15:25 Uhr

  • @duong_dajgja: Für Standard-C, StructEmptyArr ist ein Syntaxfehler (es muss mindestens ein Mitglied in der Struktur C11 §6.7.2.1 ¶2 vorhanden sein), so wie es ist EmptyStruct (Arrays der Größe Null sind in Standard-C nicht erlaubt; C11 §6.7.6.2 ¶1). GCC hat Erweiterungen, die sie möglicherweise akzeptabel machen, aber der Standard sagt “Nein”.

    – Jonathan Leffler

    19. Juli 2017 um 15:35 Uhr


  • Nebenbei: das Ergebnis von sizeof Operator ist ein size_t, also sollten Sie verwenden %zu oder ähnliches, nicht %ld.

    – Toby Speight

    19. Juli 2017 um 15:50 Uhr

Benutzeravatar von hackks
hackt

In C ist das Verhalten eines Programms undefiniert, wenn eine Struktur ohne einen benannten Member definiert ist.

C11-§6.7.2.1:

Wenn die struct-declaration-list keine benannten Member enthält, weder direkt noch über eine anonyme Struktur oder eine anonyme Vereinigung, ist das Verhalten undefiniert.

GCC erlaubt eine leere Struktur als eine Erweiterung und seine Größe wird sein 0.


Für C++, Der Standard erlaubt kein Objekt der Größe 0 und deshalb sizof(EmptyStruct) gibt den Wert 1 zurück.
Arrays der Länge Null werden von Standard-C++¹ nicht unterstützt, sind es aber als Erweiterung von GNU unterstützt und die sizeof Betreiber wird zurückkehren 0 falls angewendet.


1. § 8.5.1-Fußnote 107) C++ hat keine Arrays der Länge Null.

  • Aber er sagt, dass er den Grund versteht, warum die leere Struktur ihre Größe hat. Und die Struktur, die tut ein benanntes Mitglied hat die verwirrende Größe.

    – Johannes Schaub – litb

    19. Juli 2017 um 15:29 Uhr

  • @michael Der Code ist eindeutig nicht ISO C, da er das Tag ohne Tag-Namespace-Qualifizierer verwendet

    – Johannes Schaub – litb

    19. Juli 2017 um 15:30 Uhr

  • @michael, es ist nicht strittig, denn während Äpfel rot sind, ist mein Hemd blau und in ISO C-Strukturen muss ein benanntes Mitglied vorhanden sein, nichts davon ist relevant, da es bei der Frage nicht um Äpfel, ISO C oder mein Hemd geht

    – Johannes Schaub – litb

    19. Juli 2017 um 15:32 Uhr


  • @JohannesSchaub-litb; Es ist nicht meine Hypothese. Ebenfalls: „Wenn es sich nicht um ein Bitfeld (9.6) handelt, muss ein am meisten abgeleitetes Objekt eine Größe ungleich Null haben und ein oder mehrere Bytes Speicherplatz belegen. Unterobjekte der Basisklasse können eine Größe von Null haben.” § 1.8 (p5)

    – Hacken

    19. Juli 2017 um 16:02 Uhr


  • @hacks Sie sagen, dass der Standard Objekte der Größe 0 verbietet, und zitieren weiter, dass er solche erlaubt. Und auf eine Seite verlinken, die lediglich sagt, dass Objekte unterschiedliche Adressen haben sollen. Wenn ich die Zahlen 9+0 und 8+0 nehme, sind beide unterschiedlich, aber ich habe ihnen 0 hinzugefügt.

    – Johannes Schaub – litb

    19. Juli 2017 um 16:31 Uhr

https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html

G++ behandelt leere Strukturen so, als ob sie ein einzelnes Element vom Typ char hätten.

https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

Arrays der Länge Null sind in GNU C erlaubt. Sie sind sehr nützlich als letztes Element einer Struktur, die eigentlich ein Header für ein Objekt variabler Länge ist.

1386920cookie-checkUnterschied zwischen sizeof (leere Struktur) und sizeof (Struktur mit leerem Array)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy