typedef eine Struktur, bevor sie deklariert wird

Lesezeit: 5 Minuten

Benutzer-Avatar
Need4Steed

Ich bin kein Anfänger, ich bin mit der folgenden Redewendung sehr vertraut:

typedef struct Foo_ Foo;// I know typedef struct Foo Foo is fine, I'm just trying to make it clearer
struct Foo_
{
    int value;
    Foo *link;
};

Ich bin nur plötzlich verwirrt, weil ich verstehe, dass es nicht erlaubt ist, einen Namen (Bezeichner) zu verwenden, bevor er deklariert ist. Aber in der Deklaration typedef struct Foo_ Foodie Kennung Foo_ existiert noch nicht! Wie kommt es, dass der Compiler dies zulässt? Würde jemand bitte etwas Licht ins Dunkel bringen, mir erklären, was die Rechtfertigung für diese Art von Syntax ist?

Wikipedia-Zitat: Der Zweck von typedef besteht darin, EXISTIERENDEN Typen alternative Namen zuzuweisen.

— >8 —

Vielen Dank an alle Jungs für so viele hilfreiche Informationen.

Das ist völlig in Ordnung. Der erste Einsatz von struct Tag wie Ihres ist eine Vorwärtsdeklaration des struct Typ.

Beachten Sie jedoch, dass Ihre Verwendung von _Foo ist nicht konform. Bezeichner mit führendem Unterstrich und anschließendem Großbuchstaben sind reserviert. Tu das nicht. Nachgestellter Unterstrich wäre ok.

  • Bedeutet das typedef struct Foo_ Foo ist eigentlich struct Foo_; typedef struct Foo_ Foo; zusammengeführt?

    – Need4Steed

    29. November 2012 um 13:08 Uhr


  • Ich verstehe, es macht Sinn, weil wir so etwas schreiben können typedef struct Foo {...} Foo; wie für typedef struct Foo Foo; nur der {...} Teil entfällt.

    – Need4Steed

    29. November 2012 um 13:18 Uhr

  • Ähm, sehr schöner Thread. Ich verstehe es auch. Also, der Compiler sieht wirklich nur das struct wenn a { Anstatt von ; dh, egal wie viele struct foo;` nur wann haben struct foo { ...} das foo struct eingestellt ist. Das folgende Beispiel funktioniert sogar einschließlich -Wall -Wextra: struct foo; struct foo; struct foo { int a, b, c; char *s; };

    – Jack

    29. November 2012 um 15:06 Uhr

Benutzer-Avatar
Ekatmur

Dies wird in 6.7.2.3p8 behandelt:

6.7.2.3 Markierungen

Semantik

[…]

8 – Wenn ein Typbezeichner des Formulars struct-or-union Bezeichner tritt anders als als auf [a struct-or-union definition] oder [a struct-or-union declaration]und keine andere Deklaration des Bezeichners als Tag sichtbar ist, dann deklariert es eine unvollständige Struktur oder einen Union-Typ und deklariert den Bezeichner als Tag dieses Typs.

Der Typbezeichner struct Foo in typedef struct Foo Foo ist nicht in einer Definition (struct Foo {...};) oder eine Erklärung (struct Foo;) fällt also unter 6.7.2.3p8.

Beachten Sie, dass a nichts Besonderes ist typedef; man könnte zB auch schreiben

struct A { struct Foo *p; };

und eine vorherige Definition oder Deklaration muss nicht sichtbar sein.

In einer Funktionsdeklaration oder -definition gilt jedoch:

void foo(struct Foo *p);

wenn struct Foo vorher wird dann das nicht deklariert Umfang der Deklaration wird nur die Funktionsdeklaration oder -definition sein und ist nicht typkompatibel mit einer nachfolgenden Deklaration oder Definition von Foo.

Benutzer-Avatar
Omkant

ISO c99 : 6.2.1 Scopes of identifiers

7

Struktur-, Vereinigungs- und Aufzählungs-Tags haben einen Geltungsbereich, der unmittelbar nach dem Erscheinen des Tags in einem Typbezeichner beginnt, der das Tag deklariert.

typedef struct _Foo Foo; // You can do this because it's just the typedef the new type

struct _Foo *myfoo ; // It's pointer to struct _Foo (an incomplete type)
                      //but make sure before using myfoo->value   
                    // struct definition should be available

struct _Foo MyFoo;  // It's  definition of MyFoo but don't forget 
                    // to give the definition of struct _Foo (gcc extension). 

struct _Foo;  // forward declaration

struct _Foo    // It's the definition
{
    int value;
    Foo *link;
};

Einfach so functions wir tun forward declaration oder typedef vor der eigentlichen Definition der Funktion , also können wir es mit tun struct Auch.

void func(int );
typedef void (*func_t)(int);

void func(int x)
{
 //actual definition
}

Benutzer-Avatar
PP

typedef wird verwendet, um eine zu erstellen alias für einen Typ. Aber dieser Typ existiert nicht unbedingt, wenn er typdefiniert ist.

Zum Beispiel,

wenn du es einfach machst:

struct Foo;

und du definierst das nie struct Foo irgendwo im Programm, dann wird es trotzdem kompiliert. Der Compiler würde davon ausgehen, dass es irgendwo definiert ist, und fortfahren. Nur wenn Sie es verwenden, ohne die Struktur zu definieren, tritt ein Fehler auf.

Ähnlich verhält es sich mit typedef auch.

Unter bestimmten Umständen ist es zulässig, a zu verwenden struct ... Typ, bevor es deklariert wird. Es handelt sich dann um einen sogenannten „unvollständigen Typ“.

Beispielsweise ist es zulässig, eine Variable als Zeiger auf eine “unvollständige” Struktur zu deklarieren, sowie (wie Sie sehen können) a typedef.

Benutzer-Avatar
Mike

Es heißt Forward Declaring. Die Forward-Deklaration ermöglicht es Ihnen, den Namen im Kontext zu verwenden, in dem ein unvollständiger Typ zulässig ist.

Der Compiler “sieht” das typedef-Tag und speichert es, bis der Typ gefunden ist, also solange Sie den Typ dort nach dem typedef deklariert haben, aber vor jeder Verwendung, ist es in Ordnung.

Benutzer-Avatar
Akp

Mit einer typedef-Deklaration können Sie Ihre eigenen Bezeichner definieren, die anstelle von Typbezeichnern wie int, float und double verwendet werden können. Eine typedef-Deklaration reserviert keinen Speicherplatz.

Für mehr Information http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03typdef.htm

  • Das hat nichts mit der Frage zu tun.

    – Kiril Kirow

    29. November 2012 um 12:57 Uhr

  • @Kiril Kirov, wie Sie in Ihrer Frage erklärt haben, ist mein Verständnis, dass es nicht erlaubt ist, einen Namen (Bezeichner) zu verwenden, bevor er deklariert wird. Aber in der Deklaration typedef struct _Foo Foo existiert der Bezeichner _Foo noch nicht! aber typedef prüft nicht auf seine Existenz … das ist Yim, der die Antwort schreibt … versuchen Sie es erneut zu lesen und analysieren Sie sie dann.

    – akp

    29. November 2012 um 13:00 Uhr


  • Ich bin nicht derjenige, der die Frage gepostet hat, ich weiß, dass dies zulässig ist (es gibt sogar ein solches Beispiel in der ISO-Norm), ich glaube nur nicht, dass Ihre Antwort für die Frage relevant ist.

    – Kiril Kirow

    29. November 2012 um 13:10 Uhr

1385120cookie-checktypedef eine Struktur, bevor sie deklariert wird

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

Privacy policy