mikrocontroller.net

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


Autor: Marcel (Gast)
Datum:

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

Die Menuestruktur sieht wie folgt aus:
struct strMainMenue{
  unsigned char Entries;
  struct strEntry MenEntry[9];
};

const struct strMainMenue MainMenue=
{
  .Entries = 6,
  .MenEntry =
  {
    {//Verbrauch 'NOW'
     .mode    = 0,
     .Operate_Func = &Reset_Value,
    },  
    
    {//Verbrauch 'RESET'
     .mode    = 0,
     .Operate_Func = &Reset_Value,
    },
    
    ...
    
    {//Verbrauch 'OPTIONS'
     .mode    = 1,
     .Operate_Func = &Go_Into,
    }
  }
};


struct strSettMenue{
  unsigned char Entries;
  struct strEntry MenEntry[5];
};


const struct strSettMenue SettMenue =
{
  .Entries = 3,
  .MenEntry =
  {
    {//Uhrzeit ändern
     .mode    = 3,
     .Operate_Func = &Change_Clk,
    },

    {//Datum ändern
     .mode    = 4,
     .Operate_Func = &Change_Date,
    }
  }
}; 


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.
const struct strMainMenue volatile *ptrMenue = &MainMenue;

Wenn ich nun in das Einstellungsmenue gehe, dann lasse ich diesen 
Pointer auf die Einstellungsstruktur zeigen.
  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
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

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.