Forum: Mikrocontroller und Digitale Elektronik Bitshift: Byte in 32 Bit Variable


von Horst (Gast)


Lesenswert?

Hallo, ich habe eine einfache Frage, eigentlich nur, weil mein Compiler 
mich mit seiner Warnung etwas verwirrt:

Ich habe eine 32 Bit Variable und eine 8 Bit Variable. Nun möchte ich 
die 8 Bit-Variable an verschiedene Stellen der 32-Bit-Variable schieben, 
im Prinzip diese Byteweise auffüllen, von MSB nach LSB.

Dafür hatte ich
1
uint32_t 32bit_var = 0;
2
uint8_t 8bit_var = 0xFF;
3
4
32bit_var = (8bit_var <<16);

geshiftet, um die 8bit-variable an die zweite Byte-Stelle zu schieben:
32 Bit variable:
| 1. Byte | 8bit_var | 3. Byte | 4. Byte |

Mein Compiler sagt mir aber nun:

"Left shift count >= width of type"

Stimmt meine aktion oben oder habe ich einen Fehler gemacht?

von Peter II (Gast)


Lesenswert?

Wie gross ist denn INT auf deinem System?

> 32bit_var = (8bit_var <<16);

Wenn es 16bit ist, dann

8bit_var <<16

verlässt du hier die int Bereich.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Versuchs mal so:
1
32bit_var = ((uint32_t) 8bit_var <<16);

> Mein Compiler sagt mir aber nun:
>
> "Left shift count >= width of type"

Standardmäßig werden Ausdrücke vom Compiler in "int"-Größe "berechnet". 
Bei einem µC sind das i.d.R. 16 Bit. Wenn Du aber den Wert bereits um 16 
Bit shiftest, bist Du über die Größe eines "int" bereits hinaus.

P.S.
Ich habe bisher noch keinen C-Compiler gesehen, der Ziffern als erstes 
Zeichen in Variablennamen erlaubt ;-)

: Bearbeitet durch Moderator
von Falk B. (falk)


Lesenswert?

@ Horst (Gast)

>"Left shift count >= width of type"

Ist auch so.

>Stimmt meine aktion oben

Nein.

> oder habe ich einen Fehler gemacht?

Ja.

Du brauchst einen Cast.
1
32bit_var = ((uint32_t)8bit_var <<16);

von Holger S. (alberich)


Lesenswert?

Versuch mal
1
32bit_var = 8bit_var; 
2
32bit_var = 32bit_var << 16;
ich hab' gerade ein ähnliches Problem & hier erfahren, dass der ein- 
oder andere Compiler erst bei der Zuweisung auf den Zieltyp castet. 
Demnach könnte deiner versuchen, die 8 Bit Variable um 16 Bit zu shiften 
& die Warnung wäre nicht unbegründet :-)

von Horst (Gast)


Lesenswert?

Frank M. schrieb:
> Versuchs mal so:

Dankesehr!

Frank M. schrieb:
> Ich habe bisher noch keinen C-Compiler gesehen, der Ziffern als erstes
> Zeichen in Variablennamen erlaubt ;-)

Stimmt, das war hier nur für verdeutlichungszwecke. ;)

von Horst (Gast)


Lesenswert?

Das wird dann wohl so funktionieren.
Was ich ehrlich gesagt aber noch nicht ganz verstehe: Wenn ich in einen 
32Bit int caste, habe ich doch im Prinzip eine 32 Bit-Variable mit dem 
8Bit wert in den letzten 8 Stellen und davor Nullen.

Wenn ich diese nun shifte und in meine 32Bit-variable schreibe, die ich 
in mehreren Schritten füllen möchte (sagen wir zB mit einem 16 Bit ADC 
wert aus einer L und H variable) - überschreibe ich dann nicht die 
anderen stellen mit nullen aus der gecasteten variable? also habe ich im 
beispiel oben dann nicht

| 0x00 | 8bit_var | 3. Byte | 4. Byte |

Als ergebnis, auch wenn vorher in Byte 1 etwas anderes stand?

von Eiderdaus (Gast)


Lesenswert?

Falls ich das jetzt richtig verstanden habe: Nach der Shift-Operation 
musst Du per OR (|) verknüpfen, nicht den Wert einfach überschreiben.

von Horst (Gast)


Lesenswert?

ja, das hast du richtig verstanden. in ordnung

von Oliver (Gast)


Lesenswert?

Holger Schneider schrieb:
> ich hab' gerade ein ähnliches Problem & hier erfahren, dass der ein-
> oder andere Compiler erst bei der Zuweisung auf den Zieltyp castet.

Bei den "ein- oder anderen Compilern" handelt es sich um 100% aller C- 
und C++ - Compiler. Denn dieses Verhalten ist eindeutig den 
Sprachstandards so definiert. Sollte sich ein Compiler nicht daran 
halten, ist es auch kein C/C++-Compiler.

Oliver

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.