Frage

Ich bin Umwandlung einige 32-Bit-kompatiblen Code in 64-Bit - und ich habe einen Haken getroffen. Ich bin ein VS2008 x64 Projekt kompilieren, und ich erhalte diese Warnung:

warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits
(was 64-bit shift intended?)

Hier ist die ursprüngliche Codezeile:

if ((j & (1 << k)) != 0) {

Und hier ist, wie es aussieht, wenn ich folgen Microsofts Beratung :

if ((j & (1i64 << k)) != 0) {

Ist das sicher zu tun, wenn der Code auf 32-Bit- und 64-Bit-Systeme erstellt werden? Wenn ja, bitte erklären, warum ich „i64“ am Ende hinzufügen muß, und warum dies nicht eine 32-Bit-Kompilierung beeinflussen. Andernfalls würde eine Behelfslösung sehr geschätzt.

Darüber hinaus, ich habe, was wie ein noch schwieriges Stück Code aussieht.

if (id[j] != id[j ^ (1u << k)]) {

Ich verstehe, dass die „u“ bedeutet, dass die Ziffer nicht signiert ist, aber was ist der Punkt, dass auf einem Wert anzugeben, die nicht den unterschriebenen Maximalwert nicht überschreitet ... Ich vermute, dies etwas mit dem zu tun hat, Bit-Verschiebung?

War es hilfreich?

Lösung

1 hat Typen int nach C ++-Standard. Auf 64-Bit Microsoft Compiler int sizeof = 4 Bytes hat, bedeutet dies, dass int 32-Bit-Variable ist. 1i64 hat __int64 geben.

Wenn Sie Shift-Operator die Art des Ergebnisses verwenden ist die gleiche wie der Typ des linken Operanden. Es bedeutet, dass Verschiebung 1 Sie 32-Bit-Ergebnis zu bekommen. Microsoft Compiler geht davon aus, dass es nicht sein kann, was man erwartet (auf 64-Bit-Plattform) und gibt Ihnen eine Warnmeldung.

Wenn Sie 1i64 Ergebnis verwenden werden auf beiden Plattformen 64-Bit sein. j und 0 wird implizit auf 64-Bit gegossen werden. So ist der ganze Ausdruck wird in 64-Bit-Variablen berechnet werden und das Ergebnis wird bool werden.

So 1i64 verwendet, ist sicher auf beiden (32/64) Plattformen.

Andere Tipps

Das i64 Suffix ist Microsoft-spezifisch. Um mehr tragbar zu sein (wenn Sie darüber besorgt sind), könnten Sie die INT64_C() Makro aus stdint.h verwenden:

#include <stdint.h>

// ...

if ((j & (INT64_C( 1) << k)) != 0) { ... }

Leider ist MS nicht stdint.h als Teil ihrer C-Bibliothek hat (die meisten anderen Compilern scheinen sie zu haben), aber zum Glück kann man eine von mehreren Quellen erhalten:

Jetzt haben Sie einen 64-Bit-Konstante, die mit einer Vielzahl von Compilern arbeiten werden.

Was, warum Sie vielleicht oder müssen Sie den 64-Bit-Wert, hängt es von der Art der verschiedenen Teile des Ausdrucks. Es wäre hilfreich, die Arten von id zu wissen, j und k der Lage sein, zu beantworten, ob Sie die die ‚u‘ Suffix auf der konstanten oder nicht, müssen und welche Auswirkungen es haben könnte.

1i64 Ich glaube, sollte ein signiertes, 64-Bit-Integer sein. Ich kann keine Expertise in Microsofts Implementierung verkünden, aber in GCC, die Lösung 64-Bit-Integer auf 32-Bit-CPUs unterstützt war lange sehnen Doppelworte mit structs und verschiedener schwarzer Magie Makros zu machen. Daher i64 sollte kompatibel sein.

In Bezug auf das letzte Bit des Voodoo - der einzigen Punkt, in 1U-Angabe ist es, weil es möglich ist, dass, wenn k groß genug ist, das Ergebnis der Verschiebung würde treffen / überschreitet 32-Speicherbits, wobei in diesem Fall das Ergebnis wird anders sein, wenn die LH-Operanden als vorzeichenbehaftete oder eine nicht signierte ganze Zahl behandelt wird.

Da dieser Code ‚-Verknüpfungs den 64-Bit-Variable j mit dem (32-Bit) Ergebnis einer Bit-Verschiebung, wird das Ergebnis '' durch die Compiler zu 64 Bit erweitert.

Sie wollen wahrscheinlich in der Hand, wie der zweite Operand zum ‚und‘ berechnet werden, so dass der Compiler schlägt Ihnen die vollen 64 Bits verwenden, indem Sie den ersten Operanden macht ein __int64. Dies ist in 32-Bit-sicher, aber man sollte auf die Art der j schauen tatsächlich auf dem Bediener zu entscheiden, 32 oder 64 Bit ist.

Das ist besonders wichtig in dem zweiten Bit, wobei das Ergebnis als Index verwendet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top