Forum: Compiler & IDEs invalid use of undefined type struct


von Joachim .. (joachim_01)


Lesenswert?

invalid use of undefined type struct...

Hi,
hab hier n Problem.
In Datei lcdstuff_128x64.h steht:
1
struct  FLAGBYTE2
2
{ 
3
  unsigned char flag0 : 1;
4
  unsigned char flag1 : 1;
5
  unsigned char flag2 : 1;
6
  unsigned char flag3 : 1;
7
  unsigned char flag4 : 1;
8
  unsigned char flag5 : 1;
9
  unsigned char flag6 : 1;
10
  unsigned char flag7 : 1;  
11
} 
12
selectInput2;

in main.h:
1
// External declarations:
2
extern struct FLAGBYTE2  selectInput2;
3
extern struct FLAGBYTE stateOfButton;

in main.c:
1
switch (pActualPicture) {
2
  case 0:
3
    picture0();
4
    break;
5
                      
6
  case 1:
7
    picture1();
8
    break;
9
                      
10
  case 2:
11
    selectInput2.flag0 = 1;
12
    picture2();
13
    break;
14
                      
15
  case 3:
16
    picture3();
17
    break;
18
    
19
    .
20
    .
21
    .
22
}

das führt zu:
invalid use of undefined type 'struct FLAGBYTE2'

Merkwürdig. Ich bin mir recht sicher, daß ich die Member der Struktur 
stateOfButton ähnlich verwende, sie wird nicht bemängelt.
Jemand ne Idee?

von Oliver (Gast)


Lesenswert?

Welche header-Dateien hast du denn in main.c includiert?

Oliver

von Joachim .. (joachim_01)


Lesenswert?

Yep , deine Frage zielte in die richtige Richtung.

Ich habe mittlerweile so viele extern-Einträge und includes, daß ich 
wohl langsam den Überblick verliere;-) Was ich aber nicht verstehe: Im 
Solution Explorer ist die .h-Datei in der die Struktur deklariert wird, 
eingetragen. Trotzdem wird sie mit 'extern' in main.h nicht gefunden. 
Sollte das denn nicht gehen? Dummerweise kann ich die h.-Datei nicht 
einfach so einbinden, sie ist sehr groß, ich bekomme dann tonnenweise 
andere Fehler (Mehrfachdefs in .o-Dateien):
Error  3  multiple definition of `ctdDisableTouch'  LCDstuff_128x64.o
Error  2  first defined here  1284P_PID_main_V1_0.o

Wie macht man das verwaltungsstrategisch besser?

Meine Strategie war bis jetzt:
- main.c und main.h, nebenfunktion.c und nebenfunktion.h
- in main.c ist nebenfunktion.h NICHT icludiert
- in main.h wird mit dem Schlüsselwort extern auf die entsprechenden 
Funktionen verwiesen

Das funktioniert mit Variablen und Funktionen, mit structs 
seltsamerweise aber nicht.

von Oliver (Gast)


Lesenswert?

Was der Solution Explorer anzeigt, ist dem Compiler hezlich egal. Der 
weiß davon nichts, der sieht nur, was du in das Source-File 
hineinschreibst.

Du machst einen entscheidenden Fehler: In *.h-Dateien gehören nur 
Definitionen, keine Deklarationen, denn ansonsten wird die Variable in 
jedem Objekt angeleget, welches das headerfile inkludiert, und dann 
meckert der linker.

Das hier ist eine kombinierte Deklaration/Definition
1
struct  FLAGBYTE2
2
{ 
3
 ...
4
} 
5
selectInput2;

Die musst du aufteilen. In das header-file schreibst du:
1
struct  FLAGBYTE2
2
{ 
3
 ...
4
}
5
extern struct  FLAGBYTE2 selectInput2;

In EIN .c-File kommt dann:
1
 struct  FLAGBYTE2 selectInput2;

Dann klappts auch mit den includes ;)

Oliver

von Oliver (Gast)


Lesenswert?

Da fehlte noch ein Semikolon. So ist es besser:
1
struct  FLAGBYTE2
2
{ 
3
 ...
4
};
5
extern struct  FLAGBYTE2 selectInput2;

Oliver

von Stefan E. (sternst)


Lesenswert?

Joachim ... schrieb:
> Was ich aber nicht verstehe: Im
> Solution Explorer ist die .h-Datei in der die Struktur deklariert wird,
> eingetragen. Trotzdem wird sie mit 'extern' in main.h nicht gefunden.
> Sollte das denn nicht gehen?

Nein. Ein "extern" sorgt nicht für ein automatisches Include.

Mit "extern struct FLAGBYTE2  selectInput2;" sagst du dem Compiler nur, 
dass da irgendwo eine Variable mit Namen "selectInput2" und vom Typ 
"struct FLAGBYTE2" existiert. Wenn du aber den Header mit der 
struct-Definition nicht inkludierst, dann kennt er ja überhaupt nicht 
die Details des Typs, daher die Fehlermeldung. Da du im Header aber 
nicht nur die struct definierst, sondern auch gleich eine Variable von 
dem Typ, bekommst du beim Inkludieren in mehreren C-Dateien den 
Link-Fehler.

Joachim ... schrieb:
> Wie macht man das verwaltungsstrategisch besser?

lcdstuff_128x64.h:
Definition der struct und Deklaration der Variable
1
typedef struct { 
2
  unsigned char flag0 : 1;
3
  unsigned char flag1 : 1;
4
  unsigned char flag2 : 1;
5
  unsigned char flag3 : 1;
6
  unsigned char flag4 : 1;
7
  unsigned char flag5 : 1;
8
  unsigned char flag6 : 1;
9
  unsigned char flag7 : 1;  
10
} FLAGBYTE2;
11
12
extern FLAGBYTE2 selectInput2;

lcdstuff_128x64.c:
Definition der Variable
1
FLAGBYTE2 selectInput2;

main.c:
Interface des Moduls lcdstuff_128x64 inkludieren
1
#include "lcdstuff_128x64.h"

von Stefan E. (sternst)


Lesenswert?

Oliver schrieb:
> Du machst einen entscheidenden Fehler: In *.h-Dateien gehören nur
> Definitionen, keine Deklarationen

Umgekehrt.

von Oliver (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Umgekehrt.

Da habe ich scheller geschrieben, als gedacht ;)

Oliver

von Joachim .. (joachim_01)


Lesenswert?

Tausend Dank an euch!

von Maximilian (Gast)


Lesenswert?

Nein, das beste wäre, wenn er den extern-Kram aus seinem Header rausläßt 
und in der .c-Datei beläßt. Und direkt darüber ein "struct FLAGBYTE2;".

Abgesehen davon natürlich, daß er dringend seinen Monster-Header 
aufteilen sollte.

von Header (Gast)


Lesenswert?

Joachim ... schrieb:
> Meine Strategie war bis jetzt:
> - main.c und main.h, nebenfunktion.c und nebenfunktion.h
> - in main.c ist nebenfunktion.h NICHT icludiert
> - in main.h wird mit dem Schlüsselwort extern auf die entsprechenden
> Funktionen verwiesen

Ein Header wird als Beschreibung der Schnittstelle zu einem Modul 
genutzt. Das Modul main.c benutzt Funktionen, Variablen, Defines, usw. 
aus anderen Modulen und bindet die nötigen Deklarationen über den zum 
jeweiligen Modul gehörenden Header ein. main selber wird nirgendwo 
eingebunden und benötigt keinen eigenen Header. Das Ganze ist einfach 
und durchsichtig.

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.