Warum kann ich einen typedef-Namen des Array-Typs nicht vervollständigen?

8

Der C-Standard besagt (§6.2.5 p22):

  

Ein Array-Typ unbekannter Größe ist ein unvollständiger Typ. Es ist vollbracht,   für eine Kennung dieses Typs, indem Sie die Größe später angeben   Erklärung (mit interner oder externer Verknüpfung).

Und es funktioniert gut, was die Variablendeklarationen betrifft:

%Vor%

Aber wenn wir typedef vor diesen Deklarationen hinzufügen, beschwert sich der Compiler (ich habe auch den Namen geändert):

%Vor%

Es beschweren sich jedoch nicht, wenn wir stattdessen eine typedef zu unvollständige Struktur abschließen:

%Vor%

Der mögliche Anwendungsfall eines unvollständigen typedef von array könnte etwa so aussehen:

%Vor%

Im obigen Beispiel möchte ich einen Zeiger auf ein Array innerhalb einer Struktur mit einer Anzahl von Elementen gleich der Strukturgröße deklarieren. Ja, ich könnte eine Struktur anstelle von Array verwenden, aber warum sollte ich, wenn die obige Option möglicherweise verfügbar ist?

    
AnArrayOfFunctions 13.02.2017, 02:02
quelle

2 Antworten

4

typedef int t[2]; ist wegen der Einschränkung 6.7 / 3 nicht erlaubt:

  

Wenn ein Bezeichner keine Verknüpfung hat, darf es nicht mehr als eine Deklaration des Bezeichners (in einem Deklarator oder Typbezeichner) mit demselben Bereich und im selben Namensraum geben, außer dass:

     
  • Ein typedef-Name kann neu definiert werden, um den gleichen Typ zu bezeichnen, wie er es derzeit tut, vorausgesetzt, dass der Typ kein variabel modifizierter Typ ist;
  •   

Allerdings sind int[] und int[2] nicht vom selben Typ, so dass dieses "except" nicht zutrifft und der Code die Einschränkung verletzt.

Betreffend Ihr erstes Angebot: Obwohl 6.2.5 / 22 besagt, dass ein unvollständiger Typ vervollständigt werden kann, folgt daraus nicht, dass eine versuchte Vervollständigung automatisch legal ist. Der versuchte Abschluss muss auch mit allen anderen Regeln der Sprache übereinstimmen und in diesem Fall nicht 6.7 / 3 entsprechen.

Das int a[]; int a[2]; Beispiel ist OK (unter 6.7 / 3), weil a eine Verknüpfung hat; und in typedef struct t t1; ist struct t immer noch derselbe Typ vor und nach seiner Fertigstellung.

    
M.M 13.02.2017 02:46
quelle
0

Von 6.2.5p1 können wir eine Definition der Begriffe vollständig und unvollständig :

  

An verschiedenen Punkten innerhalb einer Übersetzungseinheit kann ein Objekttyp unvollständig sein (fehlende Informationen, um die Größe von Objekten dieses Typs zu bestimmen) oder vollständig (mit ausreichenden Informationen).

Wenn wir also davon sprechen, dass ein Typ unvollständig ist, dann sprechen wir eigentlich von der Größe der Objekte dieses Typs , die unbestimmt sind. Wir können nicht über "unvollständige Typen" sprechen, ohne ein Objekt dieses Typs zu deklarieren.

In Ihrem ersten Beispiel ist die Größe von a festgelegt, da Sie die Definition für das Objekt mithilfe der zweiten Deklaration abgeschlossen haben.

In Ihrem zweiten Beispiel wird keine Deklaration für ein Objekt gemacht. Sobald die Deklaration gemacht ist, z.B. t x = { 1, 2 }; , es wird deutlich, dass der Typ nicht unvollständig ist.

In Ihrem dritten Beispiel vervollständigen Sie nicht wirklich den Typalias; Sie vervollständigen die Definition von struct . Du hättest genauso gut schreiben können:

%Vor%

Wir können weitere Unterstützung für die Neudefinition von struct -Tags und den Ausschluss der VLA-Neudefinition in 6.7p3 :

  

Wenn ein Bezeichner keine Verknüpfung hat, darf es nicht mehr als eine Deklaration des Bezeichners (in einem Deklarator oder Typbezeichner) mit demselben Bereich und im selben Namensraum geben, außer dass:

     
  • Ein typedef-Name kann neu definiert werden, um den gleichen Typ zu bezeichnen, wie er es derzeit tut, vorausgesetzt, dass der Typ kein variabel modifizierter Typ ist;
  •   
  • -Tags können wie in 6.7.2.3 definiert neu deklariert werden.
  •   
    
Sebivor 13.02.2017 02:36
quelle

Tags und Links