如何避免按位运算的积分提升
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 位版本可能 运行 更快。
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 位版本可能 运行 更快。