Forum: Compiler & IDEs uint16_t an uint32_t zuweisen


von Micha (Gast)


Lesenswert?

ich hab gerade eine Bibliothek am Wickel, in der eine uint32_t Variable 
vorkommt. Um konkret zu sein eine etwas aufgeräumte Variante der SD-Card 
Library von Ulrich Radig. In der Library ist als Block# eine uint32_t 
Variable in Gebrauch. Da ich bei C diesbezüglich etwas misstrauisch bin 
wollte ich vorsichtshalber fragen: kann man die längere Variable 
"einfach so" aus der kürzeren zuweisen und sicher sein dass die oberen 
16 Bit Null werden, oder muss man in so einem Fall vorsorgen:
1
uint16_t b;
2
uint32_t bb;
3
.
4
.
5
.
6
  // wie weist man so etwas korrekt zu:
7
  bb = b;
8
  // oder
9
  bb = 0 | b;
10
  // oder
11
  bb = (uint32_t) b;

von gerhard (Gast)


Lesenswert?

Der Compiler würde eine einfache Zuweisung in diesem Fall akzeptieren. 
Der kleinere Typ passt in den größeren, es sind beides 
vorzeichenbehaftete Ganzzahlen, also ist ein impliziter Cast kein 
Problem.

Allerdings würde ich die letzte Variante (expliziter Cast) vorziehen, 
das ist einfach die sauberste Variante und jedem, der evtl. an deinem 
Code arbeiten muss, sieht sofort, was Sache ist.

Die mittlere Variante ist Quatsch. Obwohl, kürzlich gab es da einen 
netten Bug in PHP, wo "null plus irgendwas" auf einmal "irgendwas 
anderes" ergab. Gehört aber nicht hier hin.

von Karl H. (kbuchegg)


Lesenswert?

Weis es einfach zu.
Im Gegensatz zu meinem Vorredner würde ich keinen Cast setzen. Casts 
sind Dinge, die nach dem Muster gehen: Jeder unnötige explizite Cast ist 
ein Cast zuviel. Den technisch betrachtet, schaltet man mit einem Cast 
die Typprüfung des Compilers effektiv ab, womit dann auch 
Fehlermeldungen und Warnungen abgeschaltet werden. Daher: Casten nur 
dort, wo es notwendig ist.

von implizit (Gast)


Lesenswert?


von Peter II (Gast)


Lesenswert?

Micha schrieb:
> bb = (uint32_t) b;

kann es nicht sogar passieren, das er du den cast ein falsches ergebniss 
erzeugt weil er davon ausgeht das b 32bit ist. Damit eventuell die Daten 
im Speicher danach mit verwendet, die eigentlich nicht mehr zu b 
gehören?

von Karl H. (kbuchegg)


Lesenswert?

Nein, das kann nicht passieren.
b ist schon ein uint16_t und der Compiler weiß das auch.

Ist ja keine Pointer-Dereferenzier Operation.

von Ben j. (scarab)


Lesenswert?

Peter II schrieb:
> Micha schrieb:
>> bb = (uint32_t) b;
>
> kann es nicht sogar passieren, das er du den cast ein falsches ergebniss
> erzeugt weil er davon ausgeht das b 32bit ist. Damit eventuell die Daten
> im Speicher danach mit verwendet, die eigentlich nicht mehr zu b
> gehören?

das würde passieren wenn man

bb = *(uint32_t*)&b;

schreibt.

von Micha (Gast)


Lesenswert?

Danke an alle für die Info!

Ein wenig off topic: die Bastelei um die es hier geht hat mir persönlich 
demonstriert, dass der oft problematisierte Code von Ulrich Radig für 
SD-Cards doch problemlos funktioniert, wenn man ordentliche Hardware 
verwendet. Hatte vorher tagelang erfolglos experimentiert, allerdings 
mit Widerstandsnetzwerk zur Pegelwandlung. Jetzt, mit Pegelwandler 
MAX3392, klappt es auf Anhieb und zuverlässig.
Naja ehrlich gesagt erst im zweiten Anlauf. Im ersten hatte ich + und - 
vertauscht. Gottseidank hat es nur die SD-Card erwischt, so ein Ding ist 
zu verschmerzen...

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.