2016-11-29 85 views
0

我发现,VisualStudio 2015坚持要将WORDunsigned 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++不应该提升。这是一种糟糕的语言选择。

+0

如果此函数的输出对于程序的整体执行非常重要,那么请务必在其中放置一些汇编程序,并帮助编译器正确执行。否则,如果它仍然口感好,为什么要担心香肠里有什么? –

+0

因为它违反了类型。 C++正在拓宽不应该更广泛的东西。与其他16位值进行或“或”运算和“与”运算的16位值将永远不会溢出,并且结果是100%安全的16位值,可存储在ABI中。我不希望语​​言以任何方式促进事物的速度,在不需要任何东西的情况下产生明显的副作用(如果它想这样做是我看不见的优化,那很好,但是这具有明显的后果)强制我的代码必须改变):( – Mordachai

+1

逻辑运算,算术运算的一个子集,如果你将值声明为WORD,那么编译器可能会优化它,将小于'int'的操作数转换为'int' – doug

回答

1

为什么value提升为更大的类型?因为语言规范说它是(一个16位的unsigned short将被转换为一个32位的int)。 x86上的16位操作实际上会因相应的32位操作而受到惩罚(由于前缀操作码),所以32位版本可能运行得更快。

+0

击败我 - 小型操作在较大的CPU上往往更昂贵。 –

+0

如果要遵循规范(在OP的环境中),它应该是'int',而不是'unsigned'。“比布尔,char16_t,char32_t,或wchar_t的其整转换 秩(4.13)以外的整数类型的prvalue小于INT的秩可以被转换成一个int类型的prvalue如果INT可以表示所有 值源类型;否则,源prvalue可以转换为类型为unsigned int的prvalue。 – krzaq

+0

我不关心促销的标志 - 而是促销本身。 我可以看到有+/-促进,但位操作员只是恼人的,迫使我与无意义的铸造操作员撒我的代码。 – Mordachai