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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.