Forum: PC-Programmierung zwei 8bit Werte in ein 16bit Wert umwandeln Warnung (C)


von Paul G. (paul_g210) Benutzerseite


Lesenswert?

Moin,

bitte entschuldigt wenn ich hier für einige Meister der Programmierung 
eine viel zu triviale Frage stelle und allein deswegen Spot, Empörung 
oder Belustigung auslöse. :D

Ich habe ein uint8_t Array der Größe zwei und ich möchte eine uint16_t 
Variable mit dem Inhalt des Arrays füllen.

Ich tat dies so:
1
uint8_t array[2] = {0x22, 0x66};
2
uint16_t b = array[0]<<8 | array[1];
3
printf("0x%04X\n", b);
4
5
--> 0x2266

Der Compiler warnt mich das:
1
Warnung: Umwandlung von »int« nach »uint16_t« {aka »short unsigned int«} könnte den Wert ändern [-Wconversion]

Kann ich die Warnung in diesem Fall einfach ignorieren weil der Compiler 
anscheinend nicht weiß das ich zwei uint8_t zu einem uint16_t vereinen 
möchte oder ist meine Umwandlung nicht gut gemacht und man macht das 
generell anders?

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Das Problem liegt darin, dass die Integer-Promotion dazu führt, dass die 
Berechnung mit dem Typ int durchgeführt wird. array[0]<<8 kann dann aber 
zu einem negativen Wert führen. Du müsstest mindestens eines der beiden 
Elemente nach uint16_t casten, damit die Berechnung damit ausgeführt 
wird. Dann verschwindet auch die Warnung.

von A. S. (Gast)


Lesenswert?

Es ist gut, dass Du Warnungen an hast und sie ernst nimmst.

Was hier passiert: integer promotion sorgt dafür, dass aus dem uint8 
beim schieben ein int wird.

Sauber wäre, dass Array-Element zuerst auf uint16 zu casten.

Hier stört es nicht, aber du solltest es wissen.

Beitrag #6576652 wurde von einem Moderator gelöscht.
Beitrag #6576653 wurde von einem Moderator gelöscht.
von Rolf M. (rmagnus)


Lesenswert?

Felix schrieb im Beitrag #6576652:
> solche warnungen kannst du einfach deaktivieren. die stören nur beim
> coden.

Ja, kannste schon machen, aber dann ist es halt Sch****.

von Gerald K. (geku)


Lesenswert?

Ein CAST könnte helfen :
1
uint8_t array[2] = {0x22, 0x66}; 
2
3
uint16_t b = (uint16_t)(array[0]<<8) | (uint16_t)array[1]; 
4
printf("0x%04X\n", b);

Schließlich sollte man wissen was der CAST bewirkt. Man gibt dem 
Kompiler bekannt, dass es sich rechts um zwei Variable vom Typ  uint16 
handelt. Der Kompiler gibt dann keine Warnung mehr aus. Det CAST muss 
link und rechts vom "oder" befindlichen Werte durchgefühert werden, 
damit schon uint16 Werte miteinander vorodert werden.

Warnungen generell abzuschalten ist keine gute Lösung.

: Bearbeitet durch User
von Paul G. (paul_g210) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Integer-Promotion


Danke euch, wieder was gelernt.

Gerald K. schrieb:
> Det CAST muss link und rechts vom "oder" befindlichen Werte durchgefühert 
werden,
> damit schon uint16 Werte miteinander vorodert werden.

Det mach ich so.

von dummtipper (Gast)


Lesenswert?

eventuell hilft schon, ein U hinter die 8 zu schreiben

von A. S. (Gast)


Lesenswert?

Gerald K. schrieb:
> Det CAST muss
> link und rechts vom "oder" befindlichen Werte durchgefühert werden,
> damit schon uint16 Werte miteinander vorodert werden.

Das ist nicht richtig, siehe

Rolf M. schrieb:
> Du müsstest mindestens eines der beiden
> Elemente nach uint16_t casten, damit die Berechnung damit ausgeführt
> wird. Dann verschwindet auch die Warnung.

Ein Problem ist, dass casts eigentlich böse sind. Sie schalten praktisch 
alle Warnungen ab.

Von daher kann es sinnvoll sein, hier ohne Integer-Promotion und ohne 
casts zu arbeiten. So bleibt Warnungen bei Flüchtigkeits-Fehlern 
trotzdem erhalten:

Variante 1: Hilfsvariable
1
uint16_t h = array[0];        
2
uint16_t b = h<<8 | array[1];

Variante 2: zweistufig
1
uint16_t b = array[0];        
2
b = h<<8 | array[1];

Variante 3: eine Verknüpfung mit 0U macht alles unsigned
1
uint16_t b = 0U | array[0]<<8 | array[1];

Beitrag #6576740 wurde von einem Moderator gelöscht.
von Robinson Caruso (Gast)


Lesenswert?

Wenn int auch 2 Byte groß ist, dann kann es schiefgehen. (Wenn die Zahl 
nicht mehr durch signed int dargestellt werden kann)

von A. S. (Gast)


Lesenswert?

Robinson Caruso schrieb:
> Wenn int auch 2 Byte groß ist, dann kann es schiefgehen. (Wenn die Zahl
> nicht mehr durch signed int dargestellt werden kann)

was kann beim bisherigen Code schiefgehen und warum? Oder meinst Du wenn 
man andere Sachen (Vergleiche oder Dergleichen) macht?

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.