如何避免按位运算的积分提升

How to avoid integral promotion for bitwise operations

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)

此外,有没有办法为 WORD|WORD 获取 0x86 内在函数?我当然不想为 (16->32|16->)->16 付费。这段代码也不需要消耗超过几个 16 位寄存器,不需要几个 32 位寄存器。

不过注册表的使用真的只是一个题外话。欢迎优化器为所欲为,只要结果对我来说无法区分即可。 (即它不应该以可见的方式改变大小)。

我的主要问题是使用 flags|kFlagValue 会产生更宽的实体,然后将其放入模板会给我一个类型不匹配错误(模板比我想进入这里的要长得多,但是关键是它需要两个参数,它们应该在类型上匹配,或者可以简单地转换,但由于这个自动大小提升规则,它们不是。

如果我可以访问 "conservative bit processing function set" 那么我可以使用:

      flag non-promoting-bit-operator kFlagValue

为了达到我的目的。

我想我必须去写那个,或者到处使用强制转换,因为这个不幸的规则。

C++ 不应在这种情况下提升。这是一个糟糕的语言选择。

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