0

I'm wondering about the behavior of number literals and right-shifting, in relation to their signed-ness. Right shifting a signed integer variable can have multiple behaviors depending on the compiler, but does this apply to literals as well?

It's probably easier to ask in code:

// edited the question's values from 0x80000000 to this to avoid an integer promotion
uint32_t x = 0x7F000000 >> 4;
uint32_t y = 0x7F000000u >> 4;
uint32_t z = 0x7F000000u >> 4u;

assert(x == y && y == z);

Could this code ever fail it's assertion, given a compliant C++17 compiler?

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101
  • 1
    Right-shifting *any* signed integer value is implementation defined. Doesn't matter if the integer value is in a variable or as a literal. – Some programmer dude Nov 11 '22 at 06:30
  • 2
    I think one issue here is that `0x80000000` is not (necessarily) an `int` literal and it certainly is not an `int` literal with the sign bit set to one. Assuming you have 32 bit `int` then `0x80000000` is a `long` literal. – john Nov 11 '22 at 06:32
  • @john I believe the type of `0x80000000` is `unsigned int` according to the explanation of [The type of the literal](https://en.cppreference.com/w/cpp/language/integer_literal#The_type_of_the_literal). It's the first type in list (for hexadecimal bases) which fits the value. – Scheff's Cat Nov 11 '22 at 06:34
  • @john - Ah, I didn't consider that. would the compiler never set the sign bit in an integer literal unless you explicitly make it negative then? I'll edit my question to fix this. – Anne Quinn Nov 11 '22 at 06:34
  • @Scheff'sCat Thanks, I was unsure of that without checking. But the point remains that `0x80000000` is not a negative integer value. – john Nov 11 '22 at 06:35
  • *"Right shifting a signed integer variable"* -- one right-shifts *values*, not variables. Perhaps the shifted value is assigned back to the variable, but it is still the value that is shifted. (And once you fix that, your question kind of answers itself.) – JaMiT Nov 11 '22 at 06:35
  • @john I agree. I fiddled with [coliru](http://coliru.stacked-crooked.com/a/469fe1e206a28484) and tried to find out the reasoning for what I got. – Scheff's Cat Nov 11 '22 at 06:37
  • Regarding if `0x80000000` is an `int` or a `long`, remember that on some systems there's no difference. Most notably, MSVC keeps `long` as a 32-bit type, even on 64-bit systems. – Some programmer dude Nov 11 '22 at 06:37
  • 1
    @AnneQuinn *"would the compiler never set the sign bit in an integer literal unless you explicitly make it negative then?"* -- [There are no negative integer literals.](https://stackoverflow.com/questions/8511598/large-negative-integer-literals) So right, as long as you avoid undefined behavior, the compiler will not set the sign bit on a positive value. – JaMiT Nov 11 '22 at 06:42

0 Answers0