Ich habe den folgenden C-Code, der funktioniert:
int ex(unsigned int x) {
int mask = 0x55555555;
int a = ((x >> 0) & mask );
return a + ((x >> 1) & mask );
}
Wenn ich es jedoch erweitere, erhalte ich ein anderes Ergebnis:
int ex(unsigned int x) {
int mask = 0x55555555;
int a = ((x >> 0) & mask );
int b = ((x >> 1) & mask );
return a + b;
}
Was ist der Grund für diesen Unterschied?
EDIT: Hinweis, ich kompiliere dies für 32bit.
Verwenden Sie für Bitoperationen immer vorzeichenlose Typen.
– John
22. September 2017 um 17:01 Uhr
Nur aus Neugier, auf welcher Plattform + Compiler schlägt das eigentlich für Sie fehl und wie? Da Ich sehe keinen Unterschied zu GCC / x86-32 (außer ich füge hinzu
-ftrapv
wodurch der zweite Code wie erwartet aufgrund eines Überlaufs abstürzt).– Ilmari Karonen
22. September 2017 um 17:42 Uhr
(Die zweite Version ruft natürlich ein undefiniertes Verhalten auf, wenn die Addition überläuft. Aber auf den ersten Blick scheint es mir, dass Sie wahrscheinlich entweder finden müssten, damit sich die zweite Funktion tatsächlich anders verhält als die erste eine Plattform, auf der die Addition von vorzeichenbehafteten Ganzzahlen standardmäßig nicht umbrochen wird, oder den Compiler irgendwie dazu bringt, die Funktion einzubetten und dann eine unerwartete Optimierung vorzunehmen, basierend auf der Annahme, dass die Addition nicht überläuft.Was vermutlich stark vom tatsächlichen Aufruf abhängen würde Code; daher meine Neugier.)
– Ilmari Karonen
22. September 2017 um 17:55 Uhr
Dies ist ein vereinfachtes Code-Snippet einer größeren Funktion. Sie haben Recht, auf meiner Plattform verhalten sich diese beiden Snippets identisch, aber in der vollen Funktion taucht das Problem der impliziten Typkonvertierung auf.
– cdignam
22. September 2017 um 18:37 Uhr
Was meinst du mit “unterschiedliche Ergebnisse”? Was sind die Ergebnisse, mit welchen Werten übergeben
x
?– Benutzer5329483
29. September 2017 um 17:08 Uhr