我发现,VisualStudio 2015坚持要将WORD
(unsigned short
)提升为unsigned int
,因为只有WORD
值只涉及位操作。 (即当做16位| 16位时将16位提升为32位)。如何避免按位运算的整数提升
例如
// 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)
此外,有没有办法获得0x86 intrinsics为WORD|WORD
?我当然不想支付(16-> 32 | 16 - >) - > 16。此代码也不需要消耗多于16位的寄存器,而不是少于32位的寄存器。
但注册表的使用真的只是一个旁观。只要结果与我无法区分,优化器可以随心所欲地执行。 (即它不应以可见的方式改变尺寸)。
对我来说,主要问题是使用flags | kFlagValue会导致更广泛的实体,然后将其抽入模板会导致类型不匹配错误(模板比我想要进入的时间长得多,但是点是它需要两个参数,并且它们应该匹配类型,或者可以轻易转换,但不是,由于这个自动大小提升规则)。
如果我获得了“保守位处理功能设置”,然后我可以使用:
flag non-promoting-bit-operator kFlagValue
为了实现我的目的。
我想我必须去写那个,或者因为这个不幸的规则而使用到处都是。
在这种情况下,C++不应该提升。这是一种糟糕的语言选择。
如果此函数的输出对于程序的整体执行非常重要,那么请务必在其中放置一些汇编程序,并帮助编译器正确执行。否则,如果它仍然口感好,为什么要担心香肠里有什么? –
因为它违反了类型。 C++正在拓宽不应该更广泛的东西。与其他16位值进行或“或”运算和“与”运算的16位值将永远不会溢出,并且结果是100%安全的16位值,可存储在ABI中。我不希望语言以任何方式促进事物的速度,在不需要任何东西的情况下产生明显的副作用(如果它想这样做是我看不见的优化,那很好,但是这具有明显的后果)强制我的代码必须改变):( – Mordachai
逻辑运算,算术运算的一个子集,如果你将值声明为WORD,那么编译器可能会优化它,将小于'int'的操作数转换为'int' – doug