0

Please consider the code example where I want to check if all bits in a unsigned integer variable are set. IntegerType is replaced by uint8_t, uint16_t, uint32_t uint64_t.

The question: Why does the assertion succeed for IntegerType = uint32_t and uint64_t while it fails for uint16_t and uint8_t?

#include <cstdint>
#include <cassert>

IntegerType bitset = -1; // set all bits to true

IntegerType t = ~bitset;
bool bAllBitsSet1 = (t == 0);
bool bAllBitsSet2 = ((~bitset) == 0);

assert(bAllBitsSet1 == bAllBitsSet2);
Fabian
  • 4,001
  • 4
  • 28
  • 59

1 Answers1

5

This happens due to integer promotion: the first expression casts ~bitset back into the shorter type, while the second expression uses full integer value.

For integer types shorter than int the value gets promoted to int before performing an operation, in this case, before applying ~ to it.

Consider uint16_t for an example. When you write

uint16_t t = ~bitset;

the value of bitset gets promoted to int, so it becomes 0x0000FFFF on a 32-bit platform. Then ~ is applied, producing 0xFFFF0000. Finally, the result gets written back into t, chopping off high bits. Therefore, t is zero.

On the other hand, when you compare ~bitset to zero directly, the comparison fails, because 0xFFFF0000 is not zero.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Does promotion preserve the signed/unsigned property? Also, why does promotion take place anyway? – Fabian May 10 '18 at 18:42
  • @Fabian Promotion does not preserve the sign. If `int` can represent all values of a type, the expression gets converted to `int`. My best guess as to why this is done this way is that it's done to save CPU cycles: CPUs often operate on `int`s because they lack corresponding instructions for shorter types, so if the standard required casting back to short int, this would force compilers emit instructions that are seldom needed. Since you are given an option to keep the `int` or to cast it back, standard writers decided against requiring universal truncation. – Sergey Kalinichenko May 10 '18 at 18:48
  • " why does promotion take place anyway?" because that the way this language works https://en.cppreference.com/w/cpp/language/implicit_conversion – Slava May 10 '18 at 19:01