mikrocontroller.net

Forum: Compiler & IDEs Implizite Typumwandlung


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ingo Elsen (ogni42)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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'.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.