www.mikrocontroller.net

Forum: Compiler & IDEs shift unsigned int und shift 0x1 unterschiedlich


Autor: Fred Feuerstein (alphateilchen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich bin vor einer Weile mal auf ein für mich seltsames Verhalten
Heute habe ich mal kurz mit eclipse und mingw ein kleines testprojekt 
gezimmert das mich noch mehr verwirrt.
Unten folgt gleich der Code. Kann mir jemand erklären (oder links zu 
Specs geben) warum der shift einer variablen die 0x1 enthält, mehr oder 
weniger in einem "rotate" endet und das shiften von 0x1 direkt mit 
Zuweisung das Ergebnis 0 ergibt?(jeweils shift um mehr als die 
Datentyplänge)

Bei einem ARM7 wird in keinem der Fälle rotiert sondern die 
"rausgeschifteten" Bits werden verworfen. (mit TI compiler)

Ich weis daß es rund um das shiften bei den C Standards diverse 
"implementation defined" und "undefined" Behaviour gibt.
Ich wüsste nur gerne etwas genauer warum das unten im code scheinbar so 
uneinheitlich ist. Ich würde verstehen wenn dann generell rundum 
geschiftet wird, aber warum einmal "0" und einmal "0x8" draus wird 
verstehe ich nicht.
Ist das dadurch bedingt daß im einen Fall ein Befehl mit "imidiate 
operand" verwendet wird, wobei bei Intel immer die shiftweite per Maske 
begrenzt wird, oder ist das eine GCC Eigenheit?
Soweit ich mich erinnere verhällt sich das Visual Studio aber ähnlich.

Ich habe bisher keine Erfahrung mit eclipse daher weis ich nicht wie man 
source und assembler in einer Art mixed View wie beim Texasinstrument 
CCStudio einblendet, sonst hätte ich vieleicht schon etwas mehr 
Informationen.

Die jeweils als Kommentar angegebenen Werte stammen aus dem watch 
Fenster.

int main(void)
{
  unsigned int  ui;

  ui   = 0x1;//0x1
  ui <<= 35; //0x8 => shiftet im kreis

  ui   = 0x1;//0x1
  ui   = ui << 35;//0x8 => shiftet im kreis

  ui = 1uL<<35;//0x0  !!!!
  ui = 0x1<<35;//0x0  !!!!
...
}

Danke für Eure Hilfe

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne mich mit dem Befehlssatz des Pentium genauer auszukennen, würde ich
vermuten, dass der Prozessor vom rechten Operand der Shift-Operation nur
die untersten 5 Bits berücksichtigt. Der Ausdruck

  a << b

wird also vom Prozessor wie

  a << (b & 0x1f)

ausgeführt. Ein Links-Shift um 35 Bits führt somit zu einem Links-Shift
um 3 Bits. Das Ergebnis hat den Anschein, als ob der erste Operand
rotiert worden wäre, in Wirklichkeit wird er nur um einen um 32 zu
kleinen Wert geshiftet.

In den beiden letzten Beispielen sind beide Operanden des Shifts
konstant, so dass der Ausdruck bereits zur Compilezeit berechnet wird.
Offensichtlich verwendet der Compiler eine andere Rechenroutine
(vielleicht mit 64-Bit-Arithmetik oder mit einer Schleife), so dass eine
0 herauskommt.

Wenn du die Optimierung aktivierst, werden auch die ersten beiden
Ausdrücke bereits zur Compilezeit berechnet, so dass auch dort das
Ergebnis 0 ist.

Da In C Shifts undefiniert sind, wenn die Shiftlänge >= der
Datentypbreite ist, ist dieses Verhalten aber völlig in Ordnung.

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.