www.mikrocontroller.net

Forum: Compiler & IDEs Warnmeldung bei Pointerinitialisierung


Autor: Seby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

in einem Projekt will ich verschiedenartige Datentypen in einem EEPROM 
via SPI abspeichern. Dazu sende ich nacheinander z.B die vier Bytes 
eines double-Wertes zum SPDR Register.

So sieht das dann aus:

double double_var=1123.6;
uint8_t *ptr_double_var;
ptr_double_var=&double_var;

SPDR=*ptr_double_var;
ptr_double_var++;
SPDR=*ptr_double_var;
ptr_double_var++;
SPDR=*ptr_double_var;
ptr_double_var++;
SPDR=*ptr_double_var;

Das ganze funktioniert auch problemlos. Allerdings kommt beim komplieren 
die Warnmeldung "Assignment from incompatible pointer type".

Sollte ich den Zeiger anders initialisieren ?

Autor: Lukas K. (carrotindustries)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seby schrieb:
> double double_var=1123.6;
> uint8_t *ptr_double_var;
> ptr_double_var=&double_var;

Seby schrieb:
> "Assignment from incompatible pointer type".

Du könntest ptr_double_var als voidpointer (bäääh) initalisieren, dann 
sollte die Warnung verschwinden. BTW: Doubles haben 64bit, du musst also 
8 Bytes rausschieben.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nee, aber in den Zielpointer casten.
ptr_double_var = (uint8_t *) &double_var;

Mit AVR-GCC ist double und float in der Größe gleich und 4 Bytes groß. 
Es ist "Zufall", dass dein Programm funktioniert.

Autor: Seby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stefan
Kein Zufall. Ich habe (da ich mir nicht sicher war) die Größe eines 
doublewertes mit dem sizeof-Operator ermittelt (4 Bytes)

Autor: Stephan W. (sir_wedeck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
double double_var=1123.6;
uint8_t *ptr_double_var;

schau dir mal deine var an! Typ= double !!!
und dein Pointer ->  ..... !!!!
genau:

Assignment from incompatible pointer type

mach es mit maskierungen ist meiner bescheidenen Meinung nach sicherer!
Angenommen dein DOUBLE ist 4 Byte lang:
char bytes[4];
for( a= 0; a < 4; a++)
{
 bytes[a]= double_var & (0xff <<( a*8));
}

ist schon spät, ich hoffe es ist richtig.....

Stephan

Autor: Stephan W. (sir_wedeck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ersetze die beiden 4er mit sizeof

Stephan

Autor: Seby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich gebe zu dass ich noch nicht so lange programmiere.
Aber so wie ich es programmiert habe läuft es halt viel schneller ab. 
Bei deiner Variante dauerts duch die Schieberei doch viel länger, oder ?

Ehrlich gesagt hab ich mich von der Funktions memcpy(...) inspirieren 
lassen. Da werden doch auch nur Bytes von einer Stelle im RAM bzw. 
Registen woanders hinkopiert.

Autor: Stephan W. (sir_wedeck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, aber gut kannst die Schleife auch auf bröseln und mit const Werten 
maskiern.

Das Problem ist das double nicht gleich double ist.
>Stefan:
>Mit AVR-GCC ist double und float in der Größe gleich und 4 Bytes groß.
>Es ist "Zufall", dass dein Programm funktioniert.
die andere Vorredner haben schon recht!

Du könntest das auch mit einer Union lösen:
union{
       double dvar;
       char bytes[sizeof(double)]
};
Da kannst du dann auch direkt auf die Bytes zugreifen.

Sind halt nur irgendwie Vorschläge die wir hier machen, du musst die 
nicht übernehmen. Caste deinen Pointer bei der Zuweisung und dein 
Compiler ist glücklich. :-)

Stephan

Autor: Seby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich sollte mich erstmal mit Unions befassen. Habe bisher nur mit 
structs gearbeitet... Dann verstehe ich vielleicht auch deinen Code (-;

Autor: Stephan W. (sir_wedeck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier gefunden:

http://home.fhtw-berlin.de/~junghans/cref/SYNTAX/union.html
Mit dem Schluesselwort union legt man fest, 
dass sich mehrere Variablen verschiedenen Datentyps den gleichen Speicherplatz teilen.

Stephan

Autor: Seby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf dem gleichen Speicherplatz ? Sind sie etwa hintereinander im RAM 
abgespeichert ?

Autor: Seby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ich hab´s kapiert.

union{
       double dvar;
       char bytes[sizeof(double)]
};

Bei einem Struct wären die variablen unabhängig voneinander. Wenn ich 
der Variable dvar einen Wert zuweise würde das Array nicht geändert 
werden bzw. umgekehrt.

In diesem Fall jedoch belegt das union 4 Bytes und die Variablen decken 
sich sozusagen.

Richtig ?

Autor: Stephan W. (sir_wedeck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, richtig! :-)

Stephan

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan W. schrieb:
> Du könntest das auch mit einer Union lösen:union{
>        double dvar;
>        char bytes[sizeof(double)]
> };
> Da kannst du dann auch direkt auf die Bytes zugreifen.

Ist halt undefined behaviour.

Autor: Stephan W. (sir_wedeck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mario schrieb:
> Stephan W. schrieb:
>> Du könntest das auch mit einer Union lösen:union{
>>        double dvar;
>>        char bytes[sizeof(double)]
>> };
>> Da kannst du dann auch direkt auf die Bytes zugreifen.
>
> Ist halt undefined behaviour.

Was hab ich vergessen?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nichts.
So eine Konvertierung ist prinzipiell nicht portabel, gleich
ob man vercastete Zeiger nimmt, oder union oder sonstwas nimmt.
Insofern muß man sich nur dieser Tatsache bewusst sein und das
Konstrukt (welches auch immer) nicht unbesehen in einer anderen
Umgebung verwenden.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stephan W. schrieb:
> Mario schrieb:
>> Stephan W. schrieb:
>>> Du könntest das auch mit einer Union lösen:union{
>>>        double dvar;
>>>        char bytes[sizeof(double)]
>>> };
>>> Da kannst du dann auch direkt auf die Bytes zugreifen.
>>
>> Ist halt undefined behaviour.
>
> Was hab ich vergessen?

Dass der C-Standard vorschreibt, dass man aus einer Union nur den Typ 
zuverlässig lesen kann, den man auch als letztes beschrieben hat. Alles 
andere führt zu "undefined behaviour".

u.dvar = 1.0;
byte = u.bytes[0];
Ein Compiler könnte z.B. zur Optimierung einfach die zweite Zeile durch 
"x = 0;" ersetzen, und wäre trotzdem Standard konform. Da aber Unions 
alle Nase lang für solche Typ-Umwandlungen "misbraucht" werden, wird das 
vermutlich kein Compiler je wagen. ;-)

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.