[C ++移位,方向相同,常数不变,结果略有不同,但代码更改有所不同[重复]

问题描述 投票:0回答:1

我有模板功能

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

我想知道这是否是错误的编译器优化。有人可以解释吗?

更新:

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

c++ templates bit-manipulation compiler-optimization bit-shift
1个回答
2
投票

没有优化。由于将移位操作的结果存储在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 Shift运算符)

  1. ...操作数应为整数或无作用域枚举类型,并执行整数提升。
© www.soinside.com 2019 - 2024. All rights reserved.