Wie groß ist eine leere Struktur in C?

Lesezeit: 5 Minuten

Benutzer-Avatar
Vinit Dhatrak

Meiner Meinung nach ist es Null, aber hier scheint es ein bisschen Verwirrung zu geben

Ich habe es mit dem gcc-Compiler getestet und es gibt mir Null als Ausgabe. Ich weiß, dass in C++ die Größe einer leeren Klasse 1 ist. Lassen Sie mich wissen, wenn mir hier etwas fehlt.

  • C++ Standard (mindestens C++03) gibt dieses Ergebnis von nicht an sizeof angewendet auf eine leere Klasse/Struktur ist gleich 1.

    – Kirill W. Ljadwinski

    26. Oktober 2009 um 19:29 Uhr

Benutzer-Avatar
Johannes Schaub – litb

Eine Struktur kann in C nicht leer sein, da die Syntax dies verbietet. Darüber hinaus gibt es eine semantische Einschränkung, die das Verhalten undefiniert macht, wenn eine Struktur kein benanntes Mitglied hat:

struct-or-union-specifier:
  struct-or-union identifieropt { struct-declaration-list }
  struct-or-union identifier

struct-or-union:
  struct
  union

struct-declaration-list:
  struct-declaration
  struct-declaration-list struct-declaration

struct-declaration:
  specifier-qualifier-list struct-declarator-list ;

/* type-specifier or qualifier required here! */
specifier-qualifier-list:
  type-specifier specifier-qualifier-listopt
  type-qualifier specifier-qualifier-listopt

struct-declarator-list:
  struct-declarator
  struct-declarator-list , struct-declarator

struct-declarator:
  declarator
  declaratoropt : constant-expression

Wenn du schreibst

struct identifier { };

Es wird Ihnen eine Diagnosemeldung geben, weil Sie gegen syntaktische Regeln verstoßen. Wenn du schreibst

struct identifier { int : 0; };

Dann haben Sie eine nicht leere Struktur ohne benannte Mitglieder, wodurch das Verhalten undefiniert wird und keine Diagnose erforderlich ist:

Wenn die Strukturdeklarationsliste keine benannten Mitglieder enthält, ist das Verhalten undefiniert.

Beachten Sie, dass Folgendes nicht zulässig ist, da ein flexibles Array-Mitglied nicht das erste Mitglied sein kann:

struct identifier { type ident[]; };

  • aber der folgende Code funktioniert perfekt mit dem gcc-Compiler und gibt null aus ` struct abc { }; printf(“Größe der leeren Struktur %d\n”, sizeof(struct abc));’

    – Vinit Dhatrak

    26. Oktober 2009 um 18:35 Uhr

  • kompilieren mit -ansi -pedantic gibt “main.c:2: Warnung: Struktur hat keine Mitglieder”

    – Johannes Schaub – litb

    26. Oktober 2009 um 18:40 Uhr

  • Leere Strukturen sind eine GCC-Erweiterung.

    – Michael Burr

    26. Oktober 2009 um 18:41 Uhr

  • Ich glaube nicht, dass der C-Standard besagt, dass eine Diagnose erforderlich ist, wenn Sie gegen eine Regel verstoßen, die nur in der BNF enthalten ist. Zum größten Teil ist eine Diagnose nur dann erforderlich, wenn gegen ein „soll“ oder „soll nicht“, das in einer „Einschränkungsklausel“ enthalten ist, verstoßen wird. In C++ ist die Situation etwas anders (es gibt an, dass “The set of diagnostizierbare Regeln besteht aus allen syntaktischen und semantischen Regeln dieser Internationalen Norm…”

    – Jerry Sarg

    26. Oktober 2009 um 18:50 Uhr

  • C99 sagt zumindest: “Eine konforme Implementierung muss mindestens eine Diagnosemeldung (identifiziert auf eine implementierungsdefinierte Weise) erzeugen, wenn eine vorverarbeitende Übersetzungseinheit oder Übersetzungseinheit eine Verletzung einer Syntaxregel oder -einschränkung enthält, …”

    – Johannes Schaub – litb

    26. Oktober 2009 um 18:51 Uhr

Benutzer-Avatar
Michael Burr

Die C-Grammatik erlaubt den Inhalt von a nicht struct leer sein – es muss mindestens ein unbenanntes Bitfeld oder ein benanntes Mitglied geben (was die Grammatik betrifft – ich bin mir nicht sicher, ob eine Struktur, die nur ein unbenanntes Bitfeld enthält, ansonsten gültig ist).

Unterstützung für leere Strukturen in C sind eine Erweiterung in GCC.

In C++ ist die Angabe eines leeren Struktur-/Klassenmitglieds ausdrücklich erlaubt, aber die Größe ist auf 1 definiert – es sei denn, der Compiler darf als Teil der Optimierung der leeren Basis dafür sorgen, dass eine leere Basisklasse keinen Platz in der abgeleiteten Klasse einnimmt.

In C99: “Wenn die Strukturdeklarationsliste keine benannten Mitglieder enthält, ist das Verhalten undefiniert.”

Die Syntax erlaubt es sowieso nicht wirklich, obwohl ich nichts sehe, was besagt, dass eine Diagnose erforderlich ist, was es ziemlich genau in das Lager “undefiniertes Verhalten” zurückversetzt.

  • “Keine benannten Mitglieder” bezieht sich auf die spezifische Situation mit unbenanntem Bitfeld (siehe Antwort von litb oben). Eine einfache leere Struktur (überhaupt keine Mitglieder) ist eine Einschränkungsverletzung, nicht UB.

    – AnT steht zu Russland

    26. Oktober 2009 um 18:48 Uhr

  • Ich habe es gerade noch einmal gelesen, und ich sehe keine solche Einschränkung. Ich schaue mir §6.7.2.1 an. Die Einschränkungen, die ich sehe, befinden sich in den Absätzen 2 bis 4. Absatz 2 besagt, dass der einzige zulässige unvollständige Typ ein flexibles Array ist. Absatz 3 besagt, dass ein Bitfeld eine Breite von Null und keinen Namen haben kann, oder einen Namen und eine Breite zwischen 1 und der Größe des zugrunde liegenden Objekts. Absatz 4 besagt, dass der zugrunde liegende Typ eines Bitfelds _Bool, unsigned oder int sein soll (oder etwas anderes, das durch die Implementierung definiert ist).

    – Jerry Sarg

    26. Oktober 2009 um 19:01 Uhr

  • Es handelt sich um einen Syntaxregelverstoß, der eine Diagnosemeldung erfordert.

    – Johannes Schaub – litb

    26. Oktober 2009 um 19:11 Uhr

  • Wenn es sich um einen Verstoß gegen Syntaxregeln handelt, ist sicherlich eine Diagnose erforderlich – aber ich kann nichts sehen, was besagt, dass die BNF Teil der Syntaxregeln ist. Meistens werden sie als nicht normativ behandelt (z. B. Anhang A enthält die gesamte BNF, ist aber ausdrücklich als „informativ“ gekennzeichnet).

    – Jerry Sarg

    26. Oktober 2009 um 19:20 Uhr

  • @Jerry, die Regeln in den Abschnitten “Syntax” (wie 6.7.2.1/1 in C99) sind natürlich Syntaxregeln. Anhang A fasst nur alle Regeln zusammen, die bereits in Abschnitt 6 angegeben sind, und ist daher informativ.

    – Johannes Schaub – litb

    26. Oktober 2009 um 19:57 Uhr

Auf VC 8 gibt es einen Fehler, wenn wir versuchen, die Größe einer leeren Struktur zu erhalten, auf der anderen Seite gibt es unter Linux mit gcc die Größe 1, weil es die gcc-Erweiterung anstelle der c-Sprachspezifikation verwendet, die besagt, dass dies ein undefiniertes Verhalten ist.

struct node
{
// empty struct.
};

int main()
{
printf("%d", sizeof(struct node));
return 0;
}

unter Windows VC 2005 gibt es einen Kompilierungsfehler unter Linux mit gcc gibt es Größe 1 wegen der gcc-Erweiterung
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Empty-Structures.html#Empty-Structures
(Wie von Michael Burr hervorgehoben)

1352590cookie-checkWie groß ist eine leere Struktur in C?

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

Privacy policy