2017-05-19 3 views
4

Die IAR Embedded C-Compiler ist mit diesem glücklich, und ich nahm an, es richtig C-Code war:In C, sollte ich Zeiger auf Arrays von unvollständigen Typen verwenden dürfen?

struct incomplete; 
typedef struct incomplete (*why_not)[2]; 
struct incomplete {struct incomplete *known_to_work;} array[2]; 
why_not ok = &array; 

jedoch gcc und Klirren Drossel auf die Definition von why_not: es

incomplete.c:2:29: error: array type has incomplete element type ‘struct incomplete’ 
typedef struct incomplete (*why_not)[2]; 
          ^

Technisch ist kein Grund, eine Definition eines "pointer to array of incomplete" -Typs abzulehnen. Schließlich wird die Strukturdefinition nur benötigt, wenn eine solche Variable dereferenziert wird oder eine Zeigerarithmetik ausgeführt wird.

Ich bin bestrebt, Strukturdefinitionen wo möglich zu verbergen.

Was sagt der C-Standard dazu?

+0

Sie können einen Typ "Array von unvollständigen Typ" in keinem Fall verwenden (sogar Funktionsparameter) –

+0

@ M.M Eigentlich, warum nicht? –

+0

Fehlerbericht an IAR senden. Mist wie das ist der Grund, warum ich ihren Compiler nicht verwende. Sie haben den Mut zu verlangen, dass Sie ihnen Geld zahlen, um Fixes für ihre Non-Compliance-Bugs zu erhalten. Dies ist besonders peinlich, da dieser Teil von C seit den 1980er Jahren dort ist. – Lundin

Antwort

6

Der Code verwendet einen Array-Deklarator, bei dem der Elementtyp unvollständig ist. Dies ist eine Verletzung-Einschränkung in ISO C nach 6.7.6.2/1 Array Deklaratoren:

Constraints

Neben optional Typ Qualifizierer und das Schlüsselwort statisch, die [ und ] begrenzen kann ein Ausdruck oder *. Wenn sie einen Ausdruck begrenzen (der die Größe eines Arrays angibt), muss der Ausdruck einen Integer-Typ haben. Wenn der Ausdruck ein konstanter Ausdruck ist, sollte er einen Wert größer als Null haben. Der Elementtyp darf kein unvollständiger oder Funktionstyp sein.

5

die folgende Anweisung

typedef struct incomplete (*why_not)[2]; 

ist ein Zeiger auf ein Feld von zwei struct incomplete. Der Compiler kennt die Größe von struct incomplete noch nicht, da sie noch nicht definiert ist.

Im Folgenden wird jedoch funktionieren:

typedef struct incomplete *why_not[2]; 

d.h .: ein Array von Zeigern auf struct incomplete. Der Compiler kennt die Größe eines Zeigers auf einen unvollständigen Typ (d. H .: es ist nur die Größe, die benötigt wird, um eine Adresse zu speichern).


Edit:

Der Compiler muss nicht die Größe von struct incomplete in jedem Fall wissen (solange keine Pointer-Arithmetik stattfindet), da beide Erklärungen nur Zeiger erklärt werden.

+2

Der Compiler kennt die Größe eines Zeigers auf ein Array von unvollständiger Typ, der auch nur eine Adresse ist. Wie ich bereits erwähnt habe, gibt es mindestens einen Compiler, der dies akzeptiert. Die Frage ist, was sagt der Standard (C99 oder C11)? –

+0

@ Nicht-ein-Benutzer, Sie haben Recht. –

+0

Adressen von verschiedenen typisierten Objekten können unterschiedliche Größen haben (z.B. kann 'int *' 2 Bytes sein, während 'void * '3 Bytes ist). –

Verwandte Themen