2016-04-14 12 views
6

Ich habe einen 64-Bit langen Int mit einigen Bitfeldern darin gepackt. Ich brauche einen 16-Bit vorzeichenbehafteten int, der im zweiten und dritten Byte gespeichert ist, und füge ihn zu einem 32-Bit-Wert hinzu. Ich verwende etwas wie folgt aus:C++ beim Umwandeln in kleinere Typen abgeschnitten

u32 Function(s32 value , u64 bitfield) 
{ 
    return value + (s16) (bitfield >> 8) 
} 

Kann ich auf der Compiler angewiesen, um die Bit-Feld auf einem 16-Bit signed int zu werfen, bevor es zu einem 32-Bit signed int erweitert und führt die Addition? Wenn nicht, wie sonst sollte ich die verbleibenden Bytes abschneiden und die Typumwandlung durchführen, die ich benötige?

Antwort

6

Ja, mit dem Vorbehalt, dass Sie sich auf Compiler- und Architektur-spezifisches Verhalten verlassen. Natürlich, wenn Sie sich auf dieses Verhalten verlassen, werden Sie in wirklich schwierig zu diagnostizierende "Features" (Bugs) geraten.

Du bist wahrscheinlich besser dran, das Schreiben aus (die Compiler zu sagen), was Sie speziell möchten, lassen Sie die Optimierung Pass und andere Pässe beseitigen unnötigen Code:

u32 Function(s32 value, u64 bitfield) 
{ 
    // Extract 16 bit qty from 64-bit: (x|x|x|x|x|1|2|x), preserving 
    // signedness 
    return value + (s32) (((bitfield << 40) >> 48) & 0xffffffff); 
} 

(Ja, um einen Kommentar setzt auch dort würde help future maintainers.)

+0

Während diese Lösung die unerwünschten Informationen abschneidet, wird das Vorzeichen der 16 Bits nicht beibehalten. Ich habe überlegt, etwas zu verwenden wie: Rückgabewert + ((s32) Bitfeld << 8) >> 16); Während ich glaube, dass das funktionieren würde, finde ich es erschreckend hässlich. – Limne

+1

Ok, der Punkt, an dem Sie die Signiertheit bewahren wollten. Trotz des "Hässlichen" ist klar, was Ihre Absichten sind (Bit-Extraktion) und bewahrt die Signiertheit. Lassen Sie den Compiler die harte Arbeit der Auswahl der geeigneten Anweisungen tun. Nicht vorzeitig optimieren. –

+0

Aktualisiert, um Signedness zu erhalten und Operationen auf "Bitfield" als "u64" zu halten, bis es absolut notwendig ist. –