Warnmeldung bei Pointerinitialisierung

Gast #2027643
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 ?
#2027666
Lesenswert?

Hi,
1
double double_var=1123.6;
2
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:
1
char bytes[4];
2
for( a= 0; a < 4; a++)
3
{
4
 bytes[a]= double_var & (0xff <<( a*8));
5
}

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

Stephan
Gast #2027677
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.
#2027686
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:
1
union{
2
       double dvar;
3
       char bytes[sizeof(double)]
4
};
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
Gast #2027713
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 ?
#2027997
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.
#2028164
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".

1
u.dvar = 1.0;
2
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren