1

I have a template function

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

In Foo I do something like this

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

And it does not truncate the bits, it results in:

ORIGINAL: 10101010
RESULT: 10101010

However, if I make a slight modification

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 );

I get

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

I am wondering if this is a bad compiler optimization. Can anyone explain this?

UPDATE:

Tried this on compiler explorer, its definitely standard behavior and not a bad compiler optimization.

  • `const uint8_t RESULT_CONSTANT = ( RESULT_0_CONSTANT << OFFSET_CONSTANT );`. Shouldn't this be `const uint8_t RESULT_CONSTANT = ( RESULT_0_CONSTANT >> OFFSET_CONSTANT );` for the 2 codes to be identical. – aep May 25 '20 at 04:47
  • @aep Yep! My bad, thanks! – The Floating Brain May 25 '20 at 04:48

1 Answers1

2

There is neither optimization. There is a truncation due to storing a result of a shift operation in an object of the type uint8_t.

const uint8_t RESULT_0_CONSTANT = ( ORIGINAL_CONSTANT << OFFSET_CONSTANT );

When the shift operation is performed the integral promotions are applied to operands.

So in this expression

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

the sub-expression ( ORIGINAL_CONSTANT << OFFSET_CONSTANT ) has the type int instead of uint8_t.

From the C++ Standard (5.8 Shift operators)

  1. 1 The shift operators << and >> group left-to-right. The operands shall be of integral or unscoped enumeration type and integral promotions are performed.
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335