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

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

Powyższy kod można skompilować i połączyć za pomocą gcc w systemie Linux. Czy ktokolwiek z was mógłby mi wyjaśnić, co kryje się za Scenami? Wiem, że punkt zajmuje rozmiar pamięci, więc znacznik struct jest nieistotny dla sizeof, ale nawet włącza opcję ostrzegania w gcc, bez ostrzeżeń o strukturze "none exist" w ogóle. Kontekstem dla tego pytania jest to, że czytam jakiś kod źródłowy przez innych, próbuję bardzo ciężko znaleźć definicję "tokena struktury", ale oczywiście nie udało się.dlaczego jest możliwe użycie undefined struct w c

+6

Nie musisz 'struct żeton 'do zdefiniowania (ani nawet zadeklarowane), aby uzyskać rozmiar wskaźnika do niego. –

Odpowiedz

12

Ponieważ próbujesz uzyskać rozmiar wskaźnika na struct token. Rozmiar wskaźnika nie zależy od sposobu zdefiniowania struktury.

Ogólnie można nawet zadeklarować zmienną typu struct token*, ale nie można jej usunąć (np. Uzyskać dostęp do elementu za pomocą wskaźnika).

+0

W C++ możesz zadeklarować 'struct token *', ale nie możesz zadeklarować 'tokena *'. Nie rozumiem, dlaczego drugi nie jest dozwolony. – Deqing

+0

Bo tylko "token" nie jest niekompletnym typem, podczas gdy "token strukturalny" jest, więc kompilator nie może rozpoznać "tokenu" jako typu. Pomyśl o tym, jako o ograniczeniu składniowym. –

9

Parafrazując standard C, typ niekompletny jest typem opisującym obiekt , ale brakuje mu informacji potrzebnych do określenia jego rozmiaru.

void to kolejny niekompletny typ. W przeciwieństwie do innych niekompletnych typów, nie można wykonać pustki .

Ten "niekompletny typ" jest często używany do rodzajów uchwytów: biblioteka pozwala przydzielić "uchwyt" do czegoś, pracować z nim i ponownie go zutylizować. Wszystko to dzieje się w bibliotece. Ty jako użytkownik nie masz pojęcia, co może się wydarzyć w środku.

Przykład:

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

Jest to powszechnie znane jako [typ nieprzezroczysty] (http://en.wikipedia.org/wiki/Opaque_pointer#C) w C i można go wykorzystać do osiągnięcia mechanizmów obiektowych, takich jak enkapsulacja i polimorfizm. – Lundin

Powiązane problemy