C++位移位在相反方向上具有相同的常量,结果不同,代码更改很小

C++ Bit Shift With Same Constant in Opposite Directions, Different Result With Minor Code Changes

本文关键字:结果 代码 常量 反方向 C++      更新时间:2023-10-16

>我有一个模板函数

template< uint8_t HOW_FAR_CONSTANT, uint8_t START_CONSTANT, uint8_t ORIGINAL_CONSTANT>
uint8_t Foo();

Foo我做了这样的事情

const uint8_t OFFSET_CONSTANT = ( START_CONSTANT + HOW_FAR_CONSTANT );
const uint8_t RESULT_CONSTANT = ( ( ORIGINAL_CONSTANT << OFFSET_CONSTANT ) >> OFFSET_CONSTANT );

它不会截断位,它会导致:

ORIGINAL: 10101010
RESULT: 10101010

但是,如果我稍作修改

const uint8_t OFFSET_CONSTANT = ( START_CONSTANT + HOW_FAR_CONSTANT );
const uint8_t RESULT_0_CONSTANT = ( ORIGINAL_CONSTANT << OFFSET_CONSTANT );
const uint8_t RESULT_CONSTANT = ( RESULT_0_CONSTANT >> OFFSET_CONSTANT );

我得到

ORIGINAL: 10101010
RESULT 0 (lets say OFFSET_CONSTANT is 2): 10101000
RESULT: 00101010

我想知道这是否是一个糟糕的编译器优化。谁能解释一下?

更新:

在编译器资源管理器上尝试了这个,它绝对是标准行为,而且编译器优化还不错。

两者都没有优化。由于在类型为uint8_t的对象中存储移位操作的结果而存在截断。

const uint8_t RESULT_0_CONSTANT = ( ORIGINAL_CONSTANT << OFFSET_CONSTANT );

执行移位操作时,积分提升将应用于操作数。

所以在这个表达中

const uint8_t RESULT_CONSTANT = ( ( ORIGINAL_CONSTANT << OFFSET_CONSTANT ) >> OFFSET_CONSTANT );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

子表达式( ORIGINAL_CONSTANT << OFFSET_CONSTANT )的类型为int而不是uint8_t

从C++标准(5.8 班运算符(

  1. 1 换档操作员从左到右<<和>>分组。操作数应为整型或无作用域枚举类型,并执行整型升级