Forum: Compiler & IDEs Warnmeldung bei Pointerinitialisierung


von Seby (Gast)


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 ?

von Lukas K. (carrotindustries)


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.

von Stefan B. (stefan) Benutzerseite


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.

von Seby (Gast)


Lesenswert?

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

von Stephan W. (sir_wedeck)


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

von Stephan W. (sir_wedeck)


Lesenswert?

ersetze die beiden 4er mit sizeof

Stephan

von Seby (Gast)


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.

von Stephan W. (sir_wedeck)


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

von Seby (Gast)


Lesenswert?

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

von Stephan W. (sir_wedeck)


Lesenswert?

hier gefunden:

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

Stephan

von Seby (Gast)


Lesenswert?

Auf dem gleichen Speicherplatz ? Sind sie etwa hintereinander im RAM 
abgespeichert ?

von Seby (Gast)


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 ?

von Stephan W. (sir_wedeck)


Lesenswert?

Ja, richtig! :-)

Stephan

von Mario (Gast)


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.

von Stephan W. (sir_wedeck)


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?

von Klaus W. (mfgkw)


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.

von Stefan E. (sternst)


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. ;-)

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.