Forum: Compiler & IDEs Implizite Typumwandlung


von Markus (Gast)


Lesenswert?

Hallo,
mich interessiert das Verhalten des folgenden Codes. Ich finde weder 
hilfe in c-Büchern noch in der GCC Dokumentation.

int a = -500;
unsigned int b = 1000;
unsigned int c = 200;

if ( b > (c+a) )
{
   // code
}
else
{
   // code
}

Ist das Ergebniss des Ausdrucks (c+a) ein unsigned int oder ein signed 
int? Je nachdem wird der if oder der else Zweig ausgeführt! Ist das 
Compilerabhängig oder in ANSI C definiert?
Wer kennt eine gute Dokumentation über die implizite Typenumwandlung in 
C?

Vielen Dank
Markus

von Ingo E. (ogni42)


Lesenswert?

> Wer kennt eine gute Dokumentation über die implizite Typenumwandlung in
C?
Gut ist sicherlich eine Frage des Geschmacks, der C99 Standard ist aber 
sicherlich maßgebend:

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf

Habe jetzt nicht im Detail nachgelesen, aber es findet eine 
Vorzeichenerweiterung statt, das Ergebnis ist also signed int

von Peter D. (peda)


Lesenswert?

Es wird immer auf das höhere Format erweitert (natürliche Zahl -> 
Ganzzahl -> Kommazahl).

Bei gleichem Format wird die Länge erweitert (char -> short -> long).

Die Erweiterung erfolgt immer nach dem höchsten Quelloperanden, Ausnahme 
Schiebeoperation, da zählt nur der linke Operand.

Ein Zielüberlauf ist C völlig wurscht, da muß man selber rechtzeitig 
erweitern.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Markus wrote:

> Ist das Ergebniss des Ausdrucks (c+a) ein unsigned int oder ein signed
> int?

Es ist erstmal ein signed int.  Der wird aber beim Vergleich dann
durch einfaches gedankliches Kopieren der Bits in einen unsigned int
umgewandelt.  Falls das vorherige Ergebnis der vorzeichenbehafteten
Operation negativ war, vergleichst du auf diese Weise mit einer
sehr großen vorzeichenlosen Zahl, was sicher nicht das ist, was du
eigentlich wolltest.

Aus gutem Grund ist der Vergleich zwischen vorzeichenbehafteten und
vorzeichenlosen Zahlen dem GCC eine Warnung wert.

von Andreas K. (a-k)


Lesenswert?

Jörg Wunsch wrote:

> Es ist erstmal ein signed int.

Nein. Bei Operationen zwischen "signed int" und "unsigned int" ist das 
Ergebnis vom Typ "unsigned int". Bei gleicher Grösse gewinnt "unsigned".

Und folglich ist der Vergleich hier unproblematisch, der ist zwischen 
"unsigned" und "unsigned". Die Addition ist problematisch, und ob er da 
meckert?

PS: Alle bitte nochmal hingucken - das ist nicht die übliche 
Standardfalle mit "unsigned char" und "int", sondern "unsigned int" und 
"int", also gleiche Grösse.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas Kaiser wrote:

>> Es ist erstmal ein signed int.
>
> Nein. Bei Operationen zwischen "signed int" und "unsigned int" ist das
> Ergebnis vom Typ "unsigned int".

Sorry, ich hatte den Typ von c als `int' gelesen statt `unsigned int'.

von Markus (Gast)


Lesenswert?

Hallo,
danke für die Antworten.
Was wird eigentlich bei einem Vergleich von
((signed int)>(unsigned int))
angewendet? Ein vorzeichenbehafteter Vergleich oder ein vorzeichenloser 
Vergleich?

danke
gruss markus

von yalu (Gast)


Lesenswert?

Bei jeder binären Operation (egal, ob Rechen- oder Vergleichsopera-
tion) wird bei Integeroperanden gleicher Größe aber unterschiedlicher
Signedness der Signed-Operand vor Ausführung der Operation in unsigned
umgewandelt. Das gilt auch für dein Beispiel.

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.