Forum: Compiler & IDEs Unvollständiger Typ


von Günther F. (taraquedo)


Lesenswert?

Hallo!

Der Compiler meckert und ich komme nicht drauf, was der da meint. Kann 
mir jmd. kurz helfen, wo mein Fehler steckt? Die Meldung lautet 
"dereferencing pointer to incomplete type" und tritt in dieser Zeile 
durch die Dereferenzierung auf:
   while (position < fd->dir_entry.file_size) ...;
so (zum Testen) läuft es auch nicht, selbe Fehlermeldung:
   while (fd->pos) ...;

Dazu sind folgende Deklarationen bedeutsam:
1
   // Steht über der Zeile oben
2
   struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command);   
3
4
   // Und der Rest aus den Headern von Roland Riegel
5
   struct fat16_file_struct
6
   {
7
      ...;
8
      struct fat16_dir_entry_struct dir_entry;
9
      uint32_t pos;
10
   };
11
   struct fat16_dir_entry_struct
12
   {
13
      ...;
14
      uint32_t file_size;
15
   };

Grüße!

von Oliver (Gast)


Lesenswert?

Warum kann denn hier nienamd direkt vollständigen Code posten? Die 
Glaskugeln sind immer so anfällig.

Die o.a. Fehlermeldung besagt, daß der Compiler den Typ/struct nicht 
kennt, und deshalb auch nicht dereferenzieren kann. Warum das so ist, 
wissen die Götter...

Oliver

von Ulrich (Gast)


Lesenswert?

Hast du schon überprüft ob du die Prioritäten der Operatoren beachtet 
hast? Der Elementauswal Operator hat nämlich fast die höhste Priorität 
als der Pfeiloperator.

von Ulrich (Gast)


Lesenswert?

1. Sorry letzter Satz ist im schlechten Deutsch gescheitert ;-)
2. Oliver: Die Zeit für den Post hättest du dir sparen können. ER hat 
doch alles nennenswerte gepostet
3. Günther Frings: Falls du es nicht hinbekommst, so empfehle ich ein 
C-Buch. Ich für meinen Teil quäle da gerne mein C++ Primer Buch rum. 
Weil >>ALLES<< drinnensteht

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ulrich wrote:

> 2. Oliver: Die Zeit für den Post hättest du dir sparen können. ER hat
> doch alles nennenswerte gepostet

Hat er nicht.  Mit den geposteten Teilen ist der Fehler nicht
nachvollziehbar.  Meine Kristallkugel ist gerade aus der Reparatur
zurück und meint, dass der OP vergessen hat, das entsprechende
Headerfile auch einzubinden.  Falls sie nicht Recht hat, muss ich
sie wohl gleich wieder reklamieren...

von Ulrich (Gast)


Lesenswert?

Da ich wissen wollte ob ich auf dem richtigen Dampfer bin habe ich den 
Code (dumm wie ich bin) doch tatsächlich ins avr-Studio kopiert und habe 
gemerkt das ich auf dem falschen Dampfer war. Mit dem gegebenen 
Informationen konnte ich den Fehler wegbekommen: Hier der 
funktionsfähige Code:
1
#include <avr/io.h>
2
3
typedef struct
4
{
5
  uint32_t file_size;
6
} fat16_dir_entry_struct;
7
8
typedef struct
9
{
10
  fat16_dir_entry_struct dir_entry;
11
  uint32_t pos;
12
} fat16_file_struct;
13
14
int main(void)
15
{
16
  fat16_file_struct* fd = 0x00;   
17
  fd->dir_entry.file_size=10;
18
  return 0;
19
}

von Günther F. (taraquedo)


Lesenswert?

Hallo nochmals!

Also ich möchte nicht den Rahmen sprengen und habe deshalb nur den 
Ausschnitt des Codes gepostet, da der Quelltext inzwischen mehrere 
tausend Zeilen hat, von denen die wenigsten interessant sind.

Zum Thema Literatur: Eigentlich bin ich in C auch nicht schlecht. Ich 
programmiere bloß nicht regelmäßig, so dass ich immer wieder vergesse 
und neu lernen muss. Mit Programmieren an der Uni bin ich immer gut klar 
gekommen und ich habe auch einiges an Büchern, aus denen ich dieses 
Wissen habe. Aber ich glaube erst, wenn man es regelmäßig macht kommt 
man auch mit diesen "exotischen" Fehlern klar, die da manchmal 
entstehen. Ich wüsste nicht, wo ich das hätte nachschlagen sollen. Eine 
Datenbank mit Beispielen für diese Fehlermeldungen wäre manchmal 
hilfreich.

Was mir z.Z. nicht ganz klar ist, ist der Unterschied zwischen
   struct fat16_dir_struct
   {
      ...;
   };
und
   typedef struct
   {
      ...;
   } fat16_dir_struct;

Wunderlich finde ich auch folgendes Konstrukt im Originalcode von Roland 
Riegel, welches ich vorher nicht kannte. Hier ein Prototyp:
   struct fat16_file_struct* fat16_open_file(struct fat16_fs_struct* fs, 
const struct fat16_dir_entry_struct* dir_entry);
Hier wird struct wie ein Datentyp behandelt. Das war mir neu. Aber wenn 
ich es richtig verstehe und die 2. Definition verwende (s.o. mit 
typedef) müsste dann die gleiche Zeile ebenso nur ohne die Wörter struct 
lauten?

Mich verwirrt zunehmend, dass ich den Header fat16.h eingebunden habe. 
In ihm steht der struct fat16_dir_entry_struct und die Prototypen der 
anderen. Also so:
   struct fat16_file_struct;
   ...;
   struct fat16_dir_entry_struct { wie_gehabt; };
Trotz dem includieren des Headers bleibt der Fehler.
   struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command);
   fd->pos = 42; // <--- möööööp
Das steigt mir gerade zu Kopf. Wenn ihr nicht noch einen guten Einfall 
habt, dann poste ich morgen mal eine ganze main.c, um der Sache mal auf 
den Grund zu gehen.

Grüße!

von Günther F. (taraquedo)


Lesenswert?

Haaa!

Habe doch noch einen Fix gefunden. Es genügt nicht einen Prototyp im 
Header zu haben! Erst, wenn dort der komplette struct drin steht, dann 
versteht er es. Na das muss man natürlich wissen. Ich dachte dafür wären 
Prototypen da, um dem Compiler zu sagen "gedulde dich, so wird es 
aussehen".

Dann muss ich ja doch noch den Code von Roland anpassen. Das ist aber 
gar nicht gut. Ein Hoch auf Subversion!

Grüße!

von Günther F. (taraquedo)


Lesenswert?

...statt den gesamten Code auf den Kopf zu stellen könnte man natürlich 
auch einfach fat16_get_fs_size benutzen. vor den kopf schlag

von FBI (Gast)


Lesenswert?

Hi,
1
struct X { ...; };
2
typedef struct { ...; } Y;
3
typedef struct X Z;
die erste Zeile definiert einen Strukturtyp mit dem Namen "struct X" 
(das Schlüsselwort 'struct' ist Bestandteil des Namens). Die zweite 
Zeile definiert einen Alias "Y" für einen anonymen Strukturtyp. Und die 
dritte Zeile definiert einen Alias "Z" für für den vorher definierten 
Strukturtyp 'struct X'.
Variablen vom entsprechenden Typ werden so angelegt:
1
struct X s1;
2
Y s2;
3
Z s3;
In C++ (nicht aber in C!) ginge auch:
1
X s4;

Was die Kontstruktion
1
struct fat16_file_struct;
 im Header angeht. Hier gibt man dem Compiler nur bekannt, daß es einen 
entsprechenden Strukturtyp gib, NICHT aber wie dieser aussieht. Man kann 
diesen dann z.B. dazu verwenden um einen Zeiger darauf zu erzeugen, 
nicht aber eine Variable des Typs selbst (dafür müßte die Größe der 
Struktur bekannt sein). Zeigerarithmetik geht deshalb auch nicht. Und 
man kann natürlich auch nicht auf irgentwelche Elemente der Struktur 
zugreifen (woher soll der Compiler schließlich wissen, welche es 
überhaupt gibt)
1
struct fat16_file_struct* fd = NULL;  // das ist OK
2
struct fat16_file_struct fd2;         // "error: storage size of 'fd2' isn't known"
3
fd++;                                 // "error: increment of pointer to unknown structure"
4
                                      // "error: arithmetic on pointer to an incomplete type"
5
fd->foo = 0;                          // "error: dereferencing pointer to incomplete type"
Brauchen tut man sowas z.B., wenn zwei Strukturen Zeiger auf die jeweils 
andere enthalten.
1
struct B;
2
struct A {
3
  struct B *pB;
4
};
5
struct B {
6
  struct A *pA;
7
};

CU

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.