Frage

Ich habe eine Menge von Fragen zu diesem Thema gesehen, aber ich werde die Frage anders ohne spezifischen Code. Gibt es eine Möglichkeit von LEICHT Bestimmung dessen, was der Typ unvollständig sein verursacht? In meinem Fall bin ich mit Code jemand anderem und ich bin ganz sicher, habe ich nicht die Header richtig, aber (da Computer das Zeug zu tun viel schneller und besser als die menschliche Augäpfel) ist es eine Möglichkeit, den Compiler zu erhalten, zu sagen "hey du denken Sie Typ X in Zeile 34 haben, aber das ist eigentlich fehlt ." Der Fehler selbst nur angezeigt, wenn Sie zuweisen, was nicht sehr hilfreich ist.

War es hilfreich?

Lösung

sah ich eine Frage nach der anderen Tag, an dem jemand versehentlich einen unvollständigen Typ, die von so etwas wie

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

Der Compiler wusste, dass struct A eine Struktur war, trotz A völlig undefiniert ist, aufgrund des struct Schlüsselwort.

Das war in C ++, wo eine solche Verwendung von struct untypisch ist (und es stellt sich heraus, kann zu Fuß Schießen führen). In C, wenn Sie tun

typedef struct a {
    ...
} a;

, dann können Sie a als Typnamen und lassen Sie die struct später verwenden. Dadurch wird der Compiler führen Sie eine nicht definierte Kennung Fehler später zu geben, anstatt unvollständigen Typ, wenn Sie den Namen falsch schreiben oder einen Header vergessen.

Andere Tipps

Ein weiterer möglicher Grund ist indirekter Verweis. Wenn ein Code Verweis auf eine Struktur, die nicht in der aktuellen C-Datei enthalten ist, wird der Compiler beschweren.

  

a-> b-> c // Fehler, wenn b nicht in der aktuellen c-Datei enthält

Was meinst du, nur die Fehler angezeigt, wenn Sie zuweisen? Zum Beispiel auf GCC, ohne Zuordnung in Sicht:

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

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

Der Fehler is in Zeile 6, das ist, wo ich einen unvollständigen Typ verwendet, als ob es sich um eine komplette Art waren. Ich war in Ordnung bis dahin.

Der Fehler ist, dass Sie aufgenommen haben sollte, was Header den Typ definiert. Aber der Compiler kann möglicherweise nicht das, was Linie erraten, die an enthalten sein sollten: Jede Zeile außerhalb einer Funktion wäre in Ordnung, ziemlich viel. Weder wird es durch Datei auf Ihrem System jeden Text Schleppe, sucht einen Header, definiert es, und schlägt vor, Sie sollen das enthalten.

Alternativ (guter Punkt, potatoswatter) ist der Fehler in der Zeile, in b definiert wurde, wenn Sie bedeuten eine Art angeben, die tatsächlich existiert, aber tatsächlich angegeben blah. die Definition der Variablen b zu finden, sollte in den meisten Fällen nicht zu schwierig sein. IDEs kann es in der Regel für Sie tun, Compiler-Warnungen können vielleicht nicht gestört werden. Es ist ein paar ziemlich abscheulicher Code, obwohl, wenn Sie nicht die Definitionen der Dinge finden Sie verwenden.

Das verstehe ich nicht genau, was das Problem ist. Unvollständige Typ ist nicht der Typ, die „fehlenden“ ist. Incompete Typ ist ein Typ, ist erklärt , aber nicht definiert (im Falle von Strukturtypen). Für die Nicht-definierende Deklaration ist einfach. Wie für die die fehlende Definition zu finden ... der Compiler wird Ihnen hier nicht helfen, denn das ist, was den Fehler in erster Linie verursacht.

Ein wesentlicher Grund für unvollständigen Typfehler in C sind Fehler in Typnamen, die die Compiler von zusammenpassenden Namen zu einem anderen zu verhindern (wie in die Erklärung der Definition entspricht). Aber auch hier kann die Compiler Ihnen hier nicht helfen. Compiler nicht Vermutungen über Fehler machen.

Dieser Fehler wird normalerweise angezeigt, ob der Name Ihrer Struktur von der Initialisierung Ihrer Struktur im Code verschieden ist, so normal, c wird den Namen der Struktur finden Sie setzen und wenn die ursprüngliche Struktur nicht gefunden wird, würde dies in der Regel erscheinen, oder wenn Sie einen Zeiger darauf in dieser Zeiger zeigt, wird der Fehler angezeigt.

A - Lösung

Beim Reden für C-Sprache, habe ich gerade gefunden ampirically dass Deklarationscode folgenden wird die Lösung sein;

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

So als allgemeine Regel, gebe ich den gleichen Namen sowohl für beide Typdefinition und den Namen der Struktur;

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

B - Problemetic Proben

Dabei gilt folgende Erklärungen gelten sowohl unvollständig durch den gcc Compiler, wenn folgende Anweisung ausführen. ;

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

Und ich bekomme gleiche Fehler für den dereferenzierenden Code in der Fehlerausgabe berichtete;

>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;

Für beide der Header-Datei Erklärungen unten aufgeführt;

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

Plus dieses;

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

Außerhalb der möglichen Szenarien Vollprogrammoptimierung beteiligt, der Code-Code generiert für so etwas wie:

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

wird völlig unberührt von dem, was Mitglieder struct foo enthalten könnten. Da Make Utilities im Allgemeinen jede Übersetzungseinheit neu kompiliert werden, in dem die vollständige Definition einer Struktur angezeigt wird, selbst wenn solche Veränderungen könnten nicht den Code tatsächlich beeinflussen sie erzeugt wird, ist es üblich, komplette Strukturdefinitionen von Übersetzungseinheiten zu verzichten, die nicht wirklich braucht sie, und solche Unterlassung ist in der Regel nicht verdient eine Warnung aus.

Ein Bedarf Compiler eine vollständige Struktur oder Union Definition haben, zu wissen, wie Erklärungen zu behandeln Objekte des Typs mit automatischer oder statische Dauer, Erklärungen von Aggregaten Mitglieder des Typs oder Code enthält, die Mitglieder der Struktur oder Union zugreift. Wenn der Compiler die Information nicht benötigt, um eine der obigen Operationen auszuführen, wird es keine andere Wahl als zu Squawk über sie.

Im übrigen gibt es eine weitere Situation, in dem Standard a Compiler erlauben würde, eine vollständige Union Definition erfordern sichtbar zu sein, aber nicht eine Diagnose erforderlich: wenn zwei Strukturen mit einer gemeinsamen Anfangssequenz zu starten, und eine Vereinigung Typ beide enthält, ist sichtbar wenn der Compiler Code verarbeitet, die einen Zeiger eines der Strukturtypen prüft ein Mitglied dieser gemeinsamen Anfangssequenz verwendet, wird der Compiler erforderlich, dass ein solcher Code zu erkennen, kann das entsprechende Element einer Struktur des anderen Typs zugreift. Ich weiß nicht, was Compiler, wenn eine des Standard entsprechen, wenn der gesamte Union-Typ sichtbar ist, aber nicht, wenn es nicht [gcc ist anfällig nicht konformen Code in jedem Fall zu erzeugen, es sei denn, der -fno-strict-aliasing Flag verwendet wird, wobei in diesem Fall es wird konformen Code in beiden Fällen erzeugen], aber wenn man will Code schreiben, dass Anwendungen, die CIS-Regel in einer solchen Art und Weise, wie auf konformen Compilern korrektes Verhalten zu gewährleisten, kann man, daß eine vollständige Vereinigung Typdefinition ist sichtbar gewährleisten müssen; Geschieht dies nicht in einem Compiler falschen Code führen kann geräuschlos zu erzeugen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top