I'm floored that VisualStudio 2015 insists on promoting a WORD
(unsigned short
) to an unsigned int
when only WORD
values are involved in only bit manipulations. (i.e. promotes 16 bit to 32 bit when doing 16bit | 16bit).
e.g.
// 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)
Moreover, is there a way to get 0x86 intrinsics for WORD|WORD
? I surely do not want to pay for (16->32|16->)->16. Nor does this code need to consume more than a couple of 16 bit registers, not a few 32 bit regs.
But the registry use is really just an aside. The optimizer is welcome to do as it pleases, so long as the results are indistinguishable for me. (i.e. it should not change the size in a visible way).
The main problem for me is that using flags|kFlagValue results in a wider entity, and then pumping that into a template gives me a type mismatch error (template is rather much longer than I want to get into here, but the point is it takes two arguments, and they should match in type, or be trivially convertible, but aren't, due to this automatic size-promotion rule).
If I had access to a "conservative bit processing function set" then I could use:
flag non-promoting-bit-operator kFlagValue
To achieve my ends.
I guess I have to go write that, or use casts all over the place, because of this unfortunate rule.
C++ should not promote in this instance. It was a poor language choice.
On simple low-cost processors, typically, bitwise operations are substantially faster than division, several times faster than multiplication, and sometimes significantly faster than addition.
Some data types like char , short int take less number of bytes than int, these data types are automatically promoted to int or unsigned int when an operation is performed on them. This is called integer promotion.
Negative numbers are usually represented using two's complement instead of sign-magnitude, where you take the bitwise NOT of the positive version of the number and add one to it. So negative numbers with a small magnitude get represented by a bunch of 1's. The sum-of-2^x scheme only applies to positive numbers.
The | (bitwise inclusive OR) operator compares the values (in binary format) of each operand and yields a value whose bit pattern shows which bits in either of the operands has the value 1 . If both of the bits are 0 , the result of that bit is 0 ; otherwise, the result is 1 .
Why is value
promoted to a larger type? Because the language spec says it is (a 16-bit unsigned short
will be converted to a 32-bit int
). 16-bit ops on x86 actually incur a penalty over the corresponding 32 bit ones (due to a prefix opcode), so the 32 bit version just may run faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With