Forum: Compiler & IDEs Pointer auf Struct


von Ingo (Gast)


Lesenswert?

Hallo,

ich habe folgende Struct in der main.h:
1
struct Values_s{
2
3
  struct{
4
    struct{
5
      volatile uint16_t min,max;
6
    }Extrema, MittlereMaximalamplitude, MittlereZweiteAbleitung ;
7
  }Referenzphase, Vergleichphase;
8
9
  uint16_t Measurecounter;
10
  struct{
11
    uint16_t ProzentualerVortschritt;
12
  }Anzeige;
13
};


in der main.c dann:
1
volatile struct Values_s Daten;

dann in einer anderen C-Datei eine Funktion, die etwas mit den Variablen 
in der Struct machen soll:
1
void Get_Maxima ( uint16_t *DataPtr )
2
{
3
   /* Mach was mit den Daten */
4
  DataPtr->Measurecounter = 0;
5
}


Ich bekomme aber folgenden Fehler wenn ich die Structadresse übergebe:
1
Get_Maxima( &Daten );
 error: request for member 'Measurecounter' in something not a structure 
or union

Warum bzw. was mache ich falsch? ARM-GCC / CoIDE


Ingo

: Verschoben durch User
von Sepp (Gast)


Lesenswert?

1
void Get_Maxima ( uint16_t *DataPtr )

DataPtr ist ein uint16_t. Da gibts keine Elemente!

von Bitflüsterer (Gast)


Lesenswert?

>Warum bzw. was mache ich falsch?

Du hast den Parameter als Zeiger auf ein vorzeichenloses 16 Bit integer 
deklariert. Nicht aber als Zeiger auf eine Struktur namens Values_s.

An dieser Stelle scheint mir, der mit recht so beliebte Hinweis auf ein 
C-Buch, angebracht zu sein.

von Ingo (Gast)


Lesenswert?

Sepp schrieb:
> DataPtr ist ein uint16_t. Da gibts keine Elemente!
1
void Get_Maxima ( struct Values_s *DataPtr )

wirft diesen Fehler:
 error: dereferencing pointer to incomplete type

von Bitflüsterer (Gast)


Lesenswert?

Du solltest ohnehin schon bei der Zeile:
1
Get_Maxima( &Daten );

eine Warnung erhalten haben. Im Gegensatz zu VHDL sind Warnungen in C so 
gut wie niemals zu ignorieren.

von Ingo (Gast)


Lesenswert?

bei dieser Konstellation:
1
DataPtr->Measurecounter = 0;

von Bitflüsterer (Gast)


Lesenswert?

Ingo schrieb:
> Sepp schrieb:
>> DataPtr ist ein uint16_t. Da gibts keine Elemente!
>
>
1
> void Get_Maxima ( struct Values_s *DataPtr )
2
>
>
> wirft diesen Fehler:
>  error: dereferencing pointer to incomplete type

Schön. Was steht denn da? Das der Typ nicht komplett ist! Da fehlt also 
in dieser Datei entweder die Strukturdeklaration oder das include der 
Datei in der die Strukturdeklaration enthalten ist.

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:
> Sepp schrieb:
>> DataPtr ist ein uint16_t. Da gibts keine Elemente!
>
>
1
> void Get_Maxima ( struct Values_s *DataPtr )
2
>
>
> wirft diesen Fehler:
>  error: dereferencing pointer to incomplete type

Dann musst dann eben in diesem Teil auch das Header File inkludieren, in 
dem drinnen steht, wie die Struktur Values_s aussieht. Woher soll denn 
der COmpiler das sonst wissen? Aus den Fingern saugen?

Merke: Jedes C-File wird für sich selbst übersetzt, ohne Ansehen von 
anderen C-Files.
Was in einem anderen C-File drinnen steht, interessiert den Compiler 
schlicht und ergreifend nicht. Jedes C-File hat für sich selbst 
vollständig zu sein.

: Bearbeitet durch User
von Ingo (Gast)


Lesenswert?

warning: 'struct Values_s' declared inside parameter list [enabled by 
default]

von Bitflüsterer (Gast)


Lesenswert?

Ingo schrieb:
> warning: 'struct Values_s' declared inside parameter list [enabled by
> default]

Sollen wir raten oder ist das ein Alexandriner, oder was? :-)

von Sepp (Gast)


Lesenswert?

Probiers mal so:

*.h:
1
typedef struct
2
{
3
4
  struct{
5
    struct{
6
      volatile uint16_t min,max;
7
    }Extrema, MittlereMaximalamplitude, MittlereZweiteAbleitung ;
8
  }Referenzphase, Vergleichphase;
9
10
  uint16_t Measurecounter;
11
  struct{
12
    uint16_t ProzentualerVortschritt;
13
  }Anzeige;
14
} Values_s;

*.c:
1
volatile Values_s Daten;
2
3
void Get_Maxima (Values_s *dataptr)
4
{
5
   /* Mach was mit den Daten */
6
  dataptr->Measurecounter = 0;
7
}

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:
> warning: 'struct Values_s' declared inside parameter list [enabled by
> default]

Irgendwann wirst auch du nicht drum herum kommen, dir mal 2 Fragen zu 
stellen
* was will mir der Compiler mit dieser Fehlermeldung sagen? Was steht in 
der Fehlermeldung? Und wie lässt sich das mit den C Regeln in Einklang 
bringen?
* Warum zum Teufel hab ich eigentlich nicht längst ein C-Buch 
durchgearbeitet anstatt mich hier durch Rumraten zum Hampelmann zu 
machen?


Data.h
1
#ifndef DATA_H_INCLUDED
2
#define DATA_H_INCLUDED
3
4
struct Values_s {
5
  ...
6
};
7
8
#endif

Function.h
1
#ifndef FUNCTION_H_INCLUDED
2
#define FUNCTION_H_INCLUDED
3
4
#include "Data.h"
5
void SetData( struct Values_s * data );
6
7
#endif

main.c
1
#include "Data.h"
2
#include "Function.h"
3
4
int main()
5
{
6
  struct Values_s myData;
7
8
  SetData( &myData );
9
}

Function.c
1
#include "Function.h"
2
3
void SetData( struct Values_s * data )
4
{
5
  data-> .....
6
}

Jedes C File ist in dem Sinne vollständig, dass alle Defintionen und 
Deklarationen in jedem C-File bekannt sind. Und durch die Includes ist 
sicher gestellt, dass sie auch in allen C Files konsistent gleich sind.
Man kann jedes C-File für sich hernehmen und von jedem Begriff, der 
darin vorkommt und der kein C-Schlüsselwort ist, exakt sagen, wofür 
dieser Begriff steht bzw. welche 'innere Struktur' er hat (im Falle der 
struct). Und zwar NUR durch betrachten dieses einen C-Files in seiner 
vollständigen Form (also alle include bereits aufgelöst)


NB:
In Function.h würde es theoretisch auch eine Forward-Deklaration der 
struct tun. Es schadet aber auch nichts, wenn Function.h ganz einfach 
Data.h includiert. Die Regel ist ganz einfach: Verwendet ein C oder H 
File etwas, das in einem andern H-File definiert wird, dann wird von 
diesem C oder H File genau dieses andere H File auch includiert. 
Function.h verwendet etwas (nämlich den Namen der Struktur) aus Data.h, 
ergo hat es den include durchzuführen.

: Bearbeitet durch User
von Bitflüsterer (Gast)


Lesenswert?

Na gut. Dann nicht. Ich denke ohnhin nur, dass ich C kann bis Karl Heinz 
kommt.

von Ingo (Gast)


Lesenswert?

Danke Karl-Heinz,

deine Lösung hat geholfen, ich muss gestehen das ich K&R aber nichts 
dazu gefunden habe...


Ingo

von Bitflüsterer (Gast)


Lesenswert?

Naja. Was man alles falsch machen kann, steht in so einem Buch nicht 
d'rin. Das würde wohl leicht ein paar Tonnen wiegen.
Aber von unvollständigen und vorwärts-Deklarationen steht schon was 
darin.

von Ingo (Gast)


Lesenswert?

Was mich aufs Eis geführt hat war offensichtlich die Struct Definition / 
redefinition im Funktionsprototyp.

von A. H. (ah8)


Lesenswert?

Mal eine Frage am Rande:

Sepp schrieb:
> Probiers mal so:
>
> *.h:
>
1
typedef struct
2
{
3
4
  struct{
5
    struct{
6
      volatile uint16_t min,max;
7
    }Extrema, MittlereMaximalamplitude, MittlereZweiteAbleitung ;
8
  }Referenzphase, Vergleichphase;
9
10
  uint16_t Measurecounter;
11
  struct{
12
    uint16_t ProzentualerVortschritt;
13
  }Anzeige;
14
} Values_s;
>
> *.c:
1
volatile Values_s Daten;

Ein volatile sollte hier doch überflüssig sein, oder?

von test (Gast)


Lesenswert?

@A.H.:
Ja, das bei der Definition der Struktur ist Unsinn. Vor allem wenn er es 
danach an eine Funktion übergibt, die als Parameter keine volatile 
struct-Pointer hat.
Da sollte ebenfalls ne Warnung kommen.

@Ingo:
Kompilier deinen ganzen Kram mal zumindest mit "-Wall -pedantic" da 
sieht die Welt ot schn ganz anders aus.

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.