frage zum casten von variablen

Gast #6628686
Lesenswert?

Hallo,
ich habe eine frage zum casten in C.
1
uint32_t summe;
2
uint16_t summand_A;
3
uint16_t summand_B;
4

5
summand_A = 0xFFFF;
6
summand_B = 0xFFFF;
7

8
summe = (uint32_t)summand_A + (uint32_t)summand_B;

damit erhalte ich mein gewünschtes ergebnis (hier 0x1FFFE).

aber was passiert genau beim casten?
summand_A und summand_B haben ja einene bestimmten Platz und bereich im 
Speicher durch die definition (uint16_t summand_A;) erhalten.

Wird der gesamte speicher vom gecasteten summand_A genommen? Also auch 
die 16 bits die vor der variable stehen? Was ja jetzt uint32_t ist. Was 
ist, wenn da im Speicher irgendwas drinn steht? Dann passt das ergebnis 
ja nicht mehr.

Wenn summand_B jetzt genau hinter summand_A steht und ich es auf 
uint32_t caste, ist dann summand_B=0xFFFFFFFF (Also summand_B und das 
davorstehende summand_A)?
#6628706
Lesenswert?

Jens schrieb:
> Wird der gesamte speicher vom gecasteten summand_A genommen?

Nein, da dein summand_A kein Zeiger auf Speicher ist, sondern ein 
Integer. Mit dem Cast weist du den Compiler an, diesen Integer als 
32-Bit-Integer zu behandeln, und nicht als int-Bit-Integer.

Anders ausgedrückt: Der Compiler lädt deinen uint16_t Wert mit dem 
Cast in ein 32-Bit-Register (natürlich nur virtuell, wenn die CPU sowas 
nicht hat). Es werden also nur 16 Bit geladen und auf 32 Bit aufgebläht.

Eine Folge dessen ist, dass die Addition mit dem Cast natürlich nicht 
mehr auf "int" ausgeführt werden kann, sondern als 32-Bit-Addition 
ausgeführt werden muss, weil jetzt mindestens ein Summand 32 Bit breit 
ist.

Merke: In C hängt die Bitbreite einer Operation nicht vom Ergebnistyp 
ab, sondern von den Eingangstypen.

Einen Unterschied macht das aber nur, wenn "int" nicht ohnehin 32 Bit 
breit ist.
Gast #6628785
Lesenswert?

Arduino Fanboy D. schrieb:
> Jens schrieb:
>> summe = (uint32_t)summand_A + (uint32_t)summand_B;
> Explizite Aufweitung der Summanden

Das sind so Feinheiten, die mir auch nicht so deutlich bewusst waren 
(weil ich es sehr selten verwende).
Reicht es in deinem Beispiel auch, wenn nur einer der beiden Summanden 
auf uint32_t aufgeweitet werden? Müsste imho so sein, sonst würde das 
Beispiel mit der impliziten Aufweitung (0ul + ...) auch nicht 
funktionieren?
Gast #6628796
Lesenswert?

HildeK schrieb:
> Reicht es in deinem Beispiel auch, wenn nur einer der beiden Summanden
> auf uint32_t aufgeweitet werden?
Ja!

Der + Operator ist mehrfach überladen. Auch in C.
C++ geht da noch weiter und erlaubt eigene Überladungen.

Die wirklich ernsten Probleme mit dem Casten gibts z.B. bei Pointern
Denn da wird nur der Pointer modifiziert/umgewandelt und nicht die 
dahinterliegenden Daten.

Die Addition mit 0ul fällt übrigens der Optimierung zum Opfer, nur die 
Typeumwandlung bleibt davon erhalten.
Gast #6628806
Lesenswert?

Arduino Fanboy D. schrieb:
> HildeK schrieb:
>> Reicht es in deinem Beispiel auch, wenn nur einer der beiden Summanden
>> auf uint32_t aufgeweitet werden?
> Ja!

Das wusste ich auch noch nicht.
Aber für mich ist es momentan noch übersichtlicher es einfach vor allen 
parametern zu schreiben.

Arduino Fanboy D. schrieb:
> Die Addition mit 0ul fällt übrigens der Optimierung zum Opfer, nur die
> Typeumwandlung bleibt davon erhalten.

OK, auch nett zu wissen
#6628807
Lesenswert?

Der +-Operator bekommt bei jeder Nutzung einen bestimmten Datentyp, mit 
dem er arbeitet. Zunächst wird durch Konvertierung sichergestellt, dass 
beide Operanden den selben Typ haben, sofern du unterschiedlche Typen 
übergibst. Das Ergebnis ist dann ebenfalls von diesem Typ. Konvertierung 
heißt, dass ein temporärer Wert des Zieltyps erstellt wird, der nach der 
Operation wider verschwindet. Der ursprünglich übergebene Wert wird dazu 
also nicht angefasst.
Die Wahl des Typs hängt von den Typen der Operanden ab (und niemals 
davon, was später mit dem Ergebnis gemacht wird), aber im Prinzip wird 
der größere Typ genommen, mindestens jedoch int. Das nennt sich "integer 
promotion".

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