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?
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.
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.
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 istEmptyStruct
(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