Forum: Mikrocontroller und Digitale Elektronik Ein Pointer hat Zugriff auf unterschliedliche Structs - Menuestruktur


von Marcel (Gast)


Lesenswert?

Moin zusammen,
ich programmiere mir gerade eine Menuestruktur, die wiederum ein 
Untermenue enthält.

Die Menuestruktur sieht wie folgt aus:
1
struct strMainMenue{
2
  unsigned char Entries;
3
  struct strEntry MenEntry[9];
4
};
5
6
const struct strMainMenue MainMenue=
7
{
8
  .Entries = 6,
9
  .MenEntry =
10
  {
11
    {//Verbrauch 'NOW'
12
     .mode    = 0,
13
     .Operate_Func = &Reset_Value,
14
    },  
15
    
16
    {//Verbrauch 'RESET'
17
     .mode    = 0,
18
     .Operate_Func = &Reset_Value,
19
    },
20
    
21
    ...
22
    
23
    {//Verbrauch 'OPTIONS'
24
     .mode    = 1,
25
     .Operate_Func = &Go_Into,
26
    }
27
  }
28
};
29
30
31
struct strSettMenue{
32
  unsigned char Entries;
33
  struct strEntry MenEntry[5];
34
};
35
36
37
const struct strSettMenue SettMenue =
38
{
39
  .Entries = 3,
40
  .MenEntry =
41
  {
42
    {//Uhrzeit ändern
43
     .mode    = 3,
44
     .Operate_Func = &Change_Clk,
45
    },
46
47
    {//Datum ändern
48
     .mode    = 4,
49
     .Operate_Func = &Change_Date,
50
    }
51
  }
52
};


Wie man sieht unterscheiden sich die beiden Strukturen nur in ihrer 
Array-Größe.

Ich benutze jetzt einen Pointer, der entweder auf das Hauptmenue oder 
Das Einstellungsmenue zeigt.
1
const struct strMainMenue volatile *ptrMenue = &MainMenue;

Wenn ich nun in das Einstellungsmenue gehe, dann lasse ich diesen 
Pointer auf die Einstellungsstruktur zeigen.
1
  ptrMenue = &SettMenue; //warning: assignment from incompatible pointer type

Das Problem ist jetzt, dass &SettMenue ja eine andere Größe hat, als das 
&MainMenue. Der Compiler gibt hier kein Error aber eine Warning raus. 
Bis jetzt lief auf alles super, doch treten tritt seid kurzem ein Fehler 
in meinem Programm auf (nur wenn ich mit -Os kompiliere), sodass ich 
denke, dass ich erstmal dieses Problem hier beheben muss

In diesem Zusammenhang gibt er bei
1
if( ptrMenue == &SettMenue) //warning: comparison of distinct pointer types lacks a cast
aus.

Habt ihr eine Idee wie ich den Pointertyp zur Laufzeit ändern kann? Oder 
kann ich die Warnmeldungen sogar ignorieren, da ich weiß, dass meine 
SettMenue immer kleiner als mein Mainmenue ist?
Oder habt ihr eine Alternative  zum Aufbau der Menuestruktur?

Vielen Dank im Vorraus!

Schöne Grüße Marcel

von Hc Z. (mizch)


Lesenswert?

Mache doch statt zweier struct-Definitionen, die sich nur in der 
Arraygröße unterscheiden, eine struct mit nicht festgelegter Arraygröße 
(struct strEntry MenEntry[]) auf.  Das Array ist ja das letzte Element 
der struct, dort ist das zulässig.  Dann hast Du die ganzen Sorgen 
nicht.

von Marcel (Gast)


Lesenswert?

Hc Zimmerer schrieb:
> Mache doch statt zweier struct-Definitionen, die sich nur in der
> Arraygröße unterscheiden, eine struct mit nicht festgelegter Arraygröße
> (struct strEntry MenEntry[]) auf.  Das Array ist ja das letzte Element
> der struct, dort ist das zulässig.  Dann hast Du die ganzen Sorgen
> nicht.

Nach mehrmaligem Lesen kann ich dir nicht ganz folgen. Kannst du mir das 
nochmal etwas genauer, erklären?

Vielen Dank

Marcel

von Hc Z. (mizch)


Lesenswert?

Du definierst die Variablen strMainMenu, strSettMenu (und was sonst an 
verschieden langen Menüs noch dazukommt) als zu folgendem Typ gehörig:
1
struct strMenue{
2
  unsigned char Entries;
3
  struct strEntry MenEntry[];
4
};
Danach dieselben initialisierten const-Variablen, nur eben von diesem 
Typ.

Ich glaube übrigens eher nicht, dass Dein Aufhänger damit zusammenhängt, 
aber das ist jedenfalls die saubere Lösung des Pointer-Problems.

von Marcel (Gast)


Lesenswert?

Hc Zimmerer schrieb:
> Du definierst die Variablen strMainMenu, strSettMenu (und was sonst an
> verschieden langen Menüs noch dazukommt) als zu folgendem Typ gehörig:struct 
strMenue{
>   unsigned char Entries;
>   struct strEntry MenEntry[];
> };
> Danach dieselben initialisierten const-Variablen, nur eben von diesem
> Typ.
>
> Ich glaube übrigens eher nicht, dass Dein Aufhänger damit zusammenhängt,
> aber das ist jedenfalls die saubere Lösung des Pointer-Problems.

Supi, ich habs hinbekommen, vielen Dank!
Eine Verständnisfrage hätte ich diesbezüglich noch:
Erkennt der Compiler bei der von dir vorgeschlagenen Methode eigentlich 
automatisch, wenn zu, Beispiel dies im Code vorkommt:
[c] ptrMenue = &SettMenue; [c/], dass er den "Bereich des Pointer 
verkleinern muss", da ja in Settings weniger Menueeinträge stehen?

Vielen Dank nochmals! :-)

Grüße Marcel

von Hc Z. (mizch)


Lesenswert?

Es gibt keine Pointeroperation, bei der der Compiler die tatsächliche 
Länge der struct wissen muss bzw. den "Bereich des Pointer verkleinern 
muss".

Gibst Du bei einer Referenz auf ein Array einen zu hohen Index an, wird 
C Dir bereitwillig einen Wert liefern, der ungültig ist oder sonstwie 
undefiniertes Verhalten zeigen, egal, ob Du in der Variablendefinition 
die Arraygröße eingegeben hast oder nicht.  Anders ausgedrückt: C checkt 
Indices zur Laufzeit nicht.

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.