2016-11-29 4 views
0

ich platt bin, dass Visual Studio 2015 besteht ein WORD (unsigned short) zu einem unsigned int auf der Förderung, wenn nur WORD Werte in nur wenig Manipulationen beteiligt sind. (d.h. fördert 16 Bit bis 32 Bit, wenn 16 Bit | 16 Bit ausgeführt werden).Wie ganzheitliche Förderung für bitweise Operationen vermeiden

z.B.

// where WORD is a 'unsigned short' 
const WORD kFlag = 1; 
WORD old = 2; 
auto value = old | kFlag; // why the blazes is value an unsigned int (32 bits) 

Darüber hinaus ist es eine Möglichkeit, 0x86-Spezifika für WORD|WORD zu bekommen? Ich will sicher nicht bezahlen (16-> 32 | 16 ->) -> 16. Dieser Code benötigt auch nicht mehr als ein paar 16-Bit-Register, nicht wenige 32-Bit-Regs.

Aber die Registry-Nutzung ist wirklich nur eine Nebensache. Der Optimierer kann gerne tun, was er will, solange die Ergebnisse für mich nicht zu unterscheiden sind. (d. h. es sollte die Größe nicht sichtbar ändern).

Das Hauptproblem für mich ist, dass die Verwendung von Flags | kFlagValue zu einer breiteren Entität führt, und dann pumpt das in eine Vorlage gibt mir einen Typ Mismatch Fehler (Vorlage ist ziemlich viel länger als ich hier eingehen möchte, aber die Punkt ist, es braucht zwei Argumente, und sie sollten in Typ übereinstimmen oder Trivial konvertierbar sein, sind aber nicht, aufgrund dieser automatischen Größen-Promotion-Regel).

Wenn ich Zugriff auf eine „konservative Bit-Verarbeitung Funktion gesetzt“ hatte dann könnte ich verwenden:

 flag non-promoting-bit-operator kFlagValue 

meine Ziele zu erreichen.

Ich denke, ich muss das schreiben, oder wegen dieser unglücklichen Regel überall Güsse verwenden.

C++ sollte in diesem Fall nicht fördern. Es war eine schlechte Sprachwahl.

+0

Wenn die Ausgabe dieser Funktion für die Gesamtausführung Ihres Programms so wichtig ist, dann sollten Sie auf jeden Fall einen Assembler dort hinwerfen und dem Compiler dabei helfen, es richtig zu machen. Ansonsten, warum sich Sorgen machen, was in der Wurst ist, wenn es noch gut schmeckt? –

+0

Weil es die Typen verletzt. C++ erweitert etwas, das NIEMALS breiter sein sollte. Ein 16-Bit-Wert, der ODER-verknüpft und mit anderen 16-Bit-Werten UND-verknüpft ist, wird NIEMALS überlaufen, und die Ergebnisse sind 100% sichere 16-Bit-Werte, die in einem ABI gespeichert werden können. Ich möchte nicht, dass die Sprache Dinge willkürlich so beschleunigt, dass sichtbare Nebenwirkungen entstehen, wo keine benötigt werden (wenn sie dies als eine für mich unsichtbare Optimierung tun möchte, ist das in Ordnung, aber dies hat sichtbare Konsequenzen, die erzwinge, dass mein Code geändert werden muss) :( – Mordachai

+1

Logische Operationen, eine Teilmenge von arithmetischen Ops, konvertieren Operanden, die kleiner sind als 'int' in ein' int' – doug

Antwort

1

Warum wird value zu einem größeren Typ befördert? Weil die Sprachspezifikation dies anzeigt (ein 16-Bit unsigned short wird in ein 32-Bit int konvertiert). 16-Bit-Ops auf x86 verursachen tatsächlich einen Nachteil gegenüber den entsprechenden 32-Bit-Ops (aufgrund eines Präfix-Opcodes), so dass die 32-Bit-Version möglicherweise nur schneller läuft.

+0

Beat mich dazu - kleinere Operationen auf größeren CPUs sind in der Regel teurer. –

+0

Es sollte "int", nicht "unsigned" sein, wenn die Spezifikation eingehalten werden soll (in der Umgebung von OP)."Ein Prvalue eines ganzzahligen Typs außer bool, char16_t, char32_t oder wchar_t, dessen Ganzzahlkonvertierung Rang (4.13) kleiner als der Rang von int ist, kann in einen prvalue vom Typ int konvertiert werden, wenn int alle Werte von darstellen kann der Quellentyp; andernfalls kann der Quellprwert in einen Pr-Wert vom Typ unsigned int. konvertiert werden. " – krzaq

+0

Mir ist das Zeichen der Promotion egal - aber die Promotion selbst. Ich kann sehen, +/- zu fördern, aber Bit-Betreiber ist nur nervig und zwingt mich, meinen Code mit sinnlosen Casting-Betreibern zu besprenkeln. – Mordachai

Verwandte Themen