Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid integral promotion for bitwise operations

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.

like image 448
Mordachai Avatar asked Nov 29 '16 18:11

Mordachai


People also ask

Are bitwise operations faster than addition?

On simple low-cost processors, typically, bitwise operations are substantially faster than division, several times faster than multiplication, and sometimes significantly faster than addition.

What is integral data promotion?

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.

How do you negate a number bitwise?

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.

How does bitwise work inclusive?

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 .


1 Answers

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.

like image 87
1201ProgramAlarm Avatar answered Sep 19 '22 15:09

1201ProgramAlarm