Bitshift und Ansi C

Gast #412151
Lesenswert?

Da ich wieder mal auf die feinen Unterschiede einzelner Compiler
reingefallen bin, folgede Frage:
Welches Ergebnis liefert folgender Code in Ansi C ?

unsigned char c=128;
unsigned int i;
i=c<<8;

Steht in i eine 0 oder 32768 ?
Beide Ergbenisse hatte ich schon, je nach Compiler.

Ist eigentlich festgelegt, ob der Shift bei signed Wertden als Logical
oder Arithmetic Shift ausgeführt wird ?
Laut K&R ist das nämlich nicht festgelegt.
Die beliebte Aufteilung eines int Wertes auf 2 chars würde dann nämlich
nur manchmal bei signed Werten funktionieren.
Gast #412154
Lesenswert?

Vor einer Berechnung wie "c << 8" werden alle Integer, die kleiner als
int sind, nach int konvertiert ("integer promotion"). Wenn int 16 bits
groß ist, ist der maximale Wert 32767. Deshalb ist das Ergebnis 0. Bei
einem 32-bit-int wäre das Ergebnis 32768.
Gast #412156
Lesenswert?

@Rolf
Das heißt also, der Compiler führt einen Shift mit signed und unsigned
Werten unterschiedlich aus ?
Demzufolge müsste ein Rechtsschift auch bei einer negativen Zahl einer
Division entsprechen (abgesehen von dem Auf/Abrundungsfehler)
Gast #412157
Lesenswert?

Beim GCC ist es soweit ich weiß so. Es bietet sich ja auch an, bei
vorzeichenbehafteten Zahlen einen arithmetischen Shift zu machen, wenn
der Prozessor das unterstützt.
Allgemein sagt die Norm aber, daß es "implementation-defined" ist.
Das steht sogar schon in der Definition von "impelementation-defined"
selbst drin:

3.4.1

1 implementation-de&#64257;ned behavior
  unspeci&#64257;ed behavior where each implementation documents how
the
  choice is made

2 EXAMPLE   An example of implementation-de&#64257;ned behavior is the
  propagation of the high-order bit when a signed integer is
  shifted right.
Moderator Persönliche Seite #412158
Lesenswert?

> Vor einer Berechnung wie "c << 8" werden alle Integer, die kleiner
> als int sind, nach int konvertiert ("integer promotion"). Wenn int
> 16 bits groß ist, ist der maximale Wert 32767.

Bis hierhin gehe ich mit dir mit.

> Deshalb ist das Ergebnis 0.

Hier nicht mehr.  Der Standard erweitert den Ausdruck auf der rechten
Seite implizit zu unsigned int, wenn der normale int das Ergebnis
nicht mehr fassen kann (andernfalls müsste es ja eine integer overflow
detection geben).  Der entsprechende unsigned int Wert wird durch die
Zuweisung anschließend wieder zu int und damit eine negative Zahl bei
16-bit-Integern.

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