2012-05-25 3 views
11
#include <stdio.h> 

int main() 
{ 
    printf("%d", sizeof(struct token *)); 
} 

verwenden Der obige Code kann kompiliert werden und verwenden Sie GCC unter Linux. Könnte irgendjemand von euch das Ding hinter den Kulissen erklären? Ich weiß, dass der Punkt die Fixgröße des Speichers nimmt, so dass das Token struct irrelevant für sizeof ist, aber sogar die Warnoption in gcc aktiviert, keine Warnungen über die Struktur "none exist" überhaupt. Der Kontext für die Frage ist, dass ich etwas Quellcode von anderen lese, ich versuche sehr sehr schwer, die Definition von "struct token" zu finden, aber natürlich gescheitert.Warum ist es möglich, undefinierte Struktur in c

+6

Sie brauchen nicht 'struct Token 'zu definieren (noch nicht einmal deklariert), um die Größe eines Zeigers zu erhalten. –

Antwort

12

Weil Sie versuchen, die Größe eines Zeigers zu struct token zu erhalten. Die Größe eines Zeigers hängt nicht davon ab, wie die Struktur tatsächlich definiert ist.

Im Allgemeinen können Sie sogar eine Variable vom Typ struct token* deklarieren, aber Sie können die Variable nicht dereferenzieren (z. B. Zugriff auf ein Element über den Zeiger).

+0

In C++ können Sie 'struct token *' deklarieren, aber 'token *' nicht deklarieren. Ich verstehe nicht, warum der zweite nicht erlaubt ist. – Deqing

+0

Da nur "Token" kein unvollständiger Typ ist, während "struct token" ist, kann der Compiler "token" nicht als Typ erkennen. Betrachten Sie es als eine syntaktische Einschränkung. –

9

Um den C-Standard zu paraphrasieren, ist ein unvollständiger Typ ein Typ, der ein -Objekt beschreibt, aber keine Informationen zur Bestimmung seiner Größe enthält.

void ist ein weiterer unvollständiger Typ. Im Gegensatz zu anderen unvollständigen Typen kann void nicht abgeschlossen werden.

Dieser "unvollständige Typ" wird oft für Arten von Handle verwendet: Eine Bibliothek ermöglicht es Ihnen, einen "Handle" zu vergeben, damit zu arbeiten und ihn wieder zu entsorgen. All dies geschieht gekapselt in der Bibliothek. Sie als Benutzer haben keine Ahnung, was drinnen passieren könnte.

Beispiel:

lib.h:

struct data * d_generate(void); 
void d_set(struct data *, int); 
int d_get(struct data *); 
void d_free(struct data*); 

lib.c:

#include "lib.h" 
#include <stdlib.h> 
struct data { int value; }; 
struct data * d_generate(void) { 
    return malloc(sizeof(struct data)) 
} 
void d_set(struct data * d, int v) { 
    d -> value = v; 
} 
int d_get(struct data * d) { 
    return d->value; 
} 
void d_free(struct data* d) { 
    free(d); 
} 

user.c:

#include "lib.h" 
[...] 
struct data * d = d_generate(); 
d_set(d, 42); 
int v = d_get(d); 
// but v = d->value; doesn't work here because of the incomplete definition. 
d_free(d); 
+1

Dies ist allgemein bekannt als [undurchsichtiger Typ] (http://en.wikipedia.org/wiki/Opaque_pointer#C) in C und kann verwendet werden, um objektorientierte Mechanismen wie Kapselung und Polymorphismus zu erreichen. – Lundin

Verwandte Themen