Faszinierendes Verhalten des Right-Shift-Operators
Der Right-Shift-Operator (>>) zeigt ein eigenartiges Verhalten beim Umgang mit großen Rechts-Shift-Werten. Betrachten Sie das folgende Programm:
#include
#include
int foo(int a, int b)
{
return a >> b;
}
int bar(uint64_t a, int b)
{
return a >> b;
}
int main()
{
std::cout > 32: " > 32) > (int)32: " > (int)32) Die erwartete Ausgabe für foo(1, 32) wäre 0, aber überraschenderweise wird 1 zurückgegeben. Dies kann auf Folgendes zurückgeführt werden:
Logische Verschiebung vs. Arithmetik Shift
Auf x86/x86-64-Architekturen führt der Rechtsverschiebungsoperator tatsächlich eine logische Rechtsverschiebung durch, was bedeutet, dass er die frei gewordenen Bits mit 0 füllt, unabhängig von der Vorzeichen des linken Operanden. Das Verhalten ähnelt der Verwendung eines >>> b.
Compiler-Optimierung
Im Fall von foo(1, 32) wird der Wert 32 umgewandelt int, das effektiv auf 32 Bit gekürzt wird. Da der maximale Wert, den ein int halten kann, 231-1 beträgt, ist die Rechtsverschiebung im Wesentlichen ein >>> (32 % 32), der 0 ergibt.
Undefiniert Verhalten
Der relevante C-Standard besagt, dass „das Verhalten undefiniert ist“ für Rechtsverschiebungen mit einer Anzahl größer oder gleich der Breite des heraufgestuften linken Operanden. In diesem Fall haben sowohl 1 >> 32 als auch (int)1 >> (int)32 eine Anzahl größer als 32, was zu unvorhersehbaren Ergebnissen führt.
Unterschied mit bar(1, 32)
Die Funktionsleiste akzeptiert eine 64-Bit-Ganzzahl ohne Vorzeichen, die garantiert eine Breite größer als 32 hat. Daher wird die Rechtsverschiebung in der Leiste nicht durch undefiniertes Verhalten beeinflusst.
Schlussfolgerung
Das Verhalten des Rechtsverschiebungsoperators wird beim Umgang mit großen Verschiebungswerten mehrdeutig. Auf x86/x86-64-Architekturen wird eine logische Rechtsverschiebung durchgeführt, während auf ARM möglicherweise eine andere Implementierung verwendet wird. Aufgrund undefinierten Verhaltens sollte das Ergebnis von Rechtsverschiebungen mit einer Anzahl größer oder gleich der Breite des Operanden in portablem Code vermieden werden.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3