Domanda

Ho visto un sacco di domande su questo, ma ho intenzione di porre la domanda in modo diverso, senza codice specifico. C'è un modo di FACILMENTE per determinare che cosa sta causando il tipo di essere incompleti? Nel mio caso sto usando il codice elses qualcuno e io sono completamente sicuro non ho le intestazioni di destra, ma (dato che i computer fanno queste cose molto più velocemente e meglio di bulbi oculari umani) c'è un modo per ottenere il compilatore di dire , "ehi tu pensate è necessario digitare X alla linea 34, ma che in realtà è mancante ." L'errore si manifesta solo quando si assegna, che non è molto utile.

È stato utile?

Soluzione

Ho visto una domanda, l'altro giorno in cui qualcuno inavvertitamente usato un tipo incompleto specificando qualcosa come

struct a {
    int q; 
}; 
struct A *x; 
x->q = 3;

Il compilatore sapeva che struct A era una struct, nonostante A essere totalmente definito, in virtù della parola chiave struct.

che era in C ++, in cui tale utilizzo di struct è atipico (e, a quanto pare, può portare a piede-tiro). In C se si fa

typedef struct a {
    ...
} a;

quindi è possibile utilizzare a come typename e omettere il struct tardi. Questo porterà al compilatore di darvi un errore identificatore non definito più avanti, piuttosto che tipo incompleto, se si digitano il nome o si dimentica un colpo di testa.

Altri suggerimenti

Un'altra possibile ragione è riferimento indiretto. Se un codice riferimenti a una struttura che non inclusa nel file C corrente, il compilatore si lamentano.

  

a-> b-> c // errore se B non incluso nel file c corrente

Che cosa si intende, l'errore mostra solo quando si assegna? Ad esempio, su GCC, con nessuna assegnazione in vista:

int main() {
    struct blah *b = 0;
    *b; // this is line 6
}

incompletetype.c:6: error: dereferencing pointer to incomplete type.

L'errore è alla linea 6, che è dove è usato un tipo incompleto come se fosse un tipo completo. Mi andava bene fino a quel momento.

L'errore è che si dovrebbe aver incluso qualunque intestazione definisce il tipo. Ma il compilatore non può assolutamente indovinare linea di ciò che avrebbe dovuto essere inclusa in: qualsiasi linea esterna di una funzione andrebbe bene, più o meno. Né è vero sta per andare pesca a strascico attraverso tutti i file di testo sul vostro sistema, alla ricerca di un colpo di testa che lo definisce, e suggeriscono che si dovrebbe includere questo.

In alternativa (punto buono, potatoswatter), l'errore è in prima linea in cui è stata definita b, quando si dire per specificare un certo tipo che esiste realmente, ma in realtà blah specificato. Trovare la definizione della b variabile non dovrebbe essere troppo difficile in molti casi. IDE di solito può fare per voi, avvisi del compilatore forse non possono essere disturbati. E 'un codice abbastanza atroce, però, se non è possibile trovare le definizioni delle cose che si sta utilizzando.

Io non capisco esattamente qual è il problema. tipo incompleto non è il tipo che è "mancante". Tipo Incompete è un tipo che è ha dichiarato , ma non definito (in caso di tipi struct). Per trovare la dichiarazione di non-definizione è facile. Per quanto riguarda la ricerca la definizione manca ... il compilatore non vi aiuterà qui, dal momento che questo è ciò che ha causato l'errore, in primo luogo.

Una delle principali ragioni per errori tipo incompleto in C sono errori di battitura nei nomi tipo, che impediscono il compilatore dalla corrispondenza un nome all'altra (come in corrispondenza dichiarazione alla definizione). Ma ancora una volta, il compilatore non può aiutare qui. Compiler non fanno congetture su errori di battitura.

questo errore di solito indica se il nome del struct è diversa da quella di inizializzazione del vostro struct nel codice, così normalmente, c troverà il nome della struct si mette e se lo struct originale non viene trovato, questo di solito apparire, o se si punta un puntatore sottolineato in tale puntatore, l'errore verrà visualizzato.

A - Soluzione

Parlando per il linguaggio C, ho appena trovato ampirically che a seguito di codice della dichiarazione sarà la soluzione;

typedef struct ListNode
{
    int data;
    ListNode * prev;
    ListNode * next;
} ListNode;

Quindi, come regola generale, mi dà lo stesso nome sia per entrambi definizione del tipo e il nome del struct;

typedef struct X
{
    // code for additional types here
    X* prev; // reference to pointer
    X* next; // reference to pointer
} X;

B - Campioni Problemetic

Dove seguenti dichiarazioni sono considerati sia incompleta dal compilatore gcc durante l'esecuzione seguente dichiarazione. ;

removed->next->prev = removed->prev;

E ottengo lo stesso errore per il codice dereferenziazione riportato l'output di errore;

>gcc Main.c LinkedList.c -o Main.exe -w
LinkedList.c: In function 'removeFromList':
LinkedList.c:166:18: error: dereferencing pointer to incomplete type 'struct ListNode'
     removed->next->prev = removed->prev;

Per entrambi il file di intestazione le dichiarazioni di seguito elencati;

typedef struct
{
    int data;
    ListNode * prev;
    ListNode * next;
} ListNode;

Inoltre questo;

typedef struct ListNodeType
{
    int data;
    ListNode * prev;
    ListNode * next;
} ListNode;

Al di fuori di possibili scenari che coinvolgono l'ottimizzazione dell'intero programma, il codice generato per qualcosa come:

struct foo *bar;
struct foo *test(struct foo *whatever, int blah)
{
  return blah ? whatever: bar;
}

sarà totalmente influenzato da ciò che i membri struct foo potrebbe contenere. A causa di make utilità in genere ricompilare ogni unità di compilazione in cui la definizione completa di una struttura appare, anche quando tali modifiche non potrebbe effettivamente influenzare il codice generato per loro, è comune a omettere le definizioni struttura completa di unità di compilazione che in realtà non necessità loro, e tale omissione non è generalmente degno di un avvertimento.

esigenze compilatore A abbia una struttura o unione definizione completa di sapere come gestire dichiarazioni oggetti del tipo a durata automatico o statico, dichiarazioni di aggregati contenenti componenti del tipo o codice che accede membri della struttura o unione. Se il compilatore non ha le informazioni necessarie per eseguire una delle operazioni di cui sopra, non avrà altra scelta che squawk su di esso.

Per inciso, non c'è una situazione più in cui la norma permetterebbe un compilatore da richiedere una definizione completa unione di essere visibile, ma non richiederebbe una diagnosi: se due strutture iniziano con una sequenza iniziale comune, e un tipo di unione che contiene sia visibile quando il compilatore elabora codice che utilizza un puntatore di uno dei tipi di struttura a ispeziona un socio di tale sequenza iniziale comune, il compilatore deve rilevare che tale codice potrebbe accedere corrispondente organo di una struttura di altro tipo. Non so che cosa compilatori eventuale conformi alla norma quando il tipo di unione completa è visibile ma non quando non lo è [gcc è incline a generare il codice non conforme in entrambi i casi se non si utilizza il flag -fno-strict-aliasing, nel qual caso esso genererà conforme codice in entrambi i casi] ma se uno vuole scrivere il codice che utilizza la regola CIS in modo tale da garantire un comportamento corretto sul conforme compilatori, uno potrebbe essere necessario per assicurare che tipo di unione completa definizione è visibile; in caso contrario si può provocare un compilatore silenziosamente generare il codice falso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top