1

My program is written below:

void main() {
   int n =0;
   printf("%x", (~0 << (32+ (~n +1) )));
}

As n = 0, ~n = 0xffffffff == -1, so ~n + 1 is equal to 0. When I execute this program, I get 0xffffffff, which is incorrect as (~0 << 32 ) outputs 0.

When I replace (~n +1) with 0, it outputs 0.

Any help is very much appreciated.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Kumar Vikramjeet
  • 253
  • 1
  • 4
  • 13
  • 3
    Possible duplicate of http://stackoverflow.com/questions/11270492/what-does-the-c-standard-say-about-bitshifting-more-bits-than-the-width-of-type – mafso Sep 01 '14 at 19:28
  • 2
    @mafso: I don't see how? _[edit: okay, that question should say "greater than or equal to", but it's still not a duplicate]_ – Lightness Races in Orbit Sep 01 '14 at 19:28
  • Also, you should use `int main()` instead of `void main()` – milleniumbug Sep 01 '14 at 19:34
  • Using `%x` to output an `int` also causes undefined behaviour. Use `%d`, or make the thing you're outputting be an `unsigned int`. – M.M Sep 01 '14 at 22:51
  • Also related to [Why doesn't this swap macro using shifts not work for negative numbers?](http://stackoverflow.com/questions/24565837/why-doesnt-this-swap-macro-using-shifts-not-work-for-negative-numbers) – Shafik Yaghmour Sep 03 '14 at 02:09

1 Answers1

6

You're shifting a 32-bit wide value by 32 bits.
The result is undefined and could equal mushroom lasagna for all you know.

[C99: 6.5.7/3]: The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

Any further analysis, then, is folly.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Thanks! I read that clause, but I don't get why the behavior is consistent in both cases. – Kumar Vikramjeet Sep 01 '14 at 19:41
  • 2
    @KumarVikramjeet: You mean inconsistent? IIRC, on x86, only the 5 lowest bits of the right operand are used for shifts with 32 bit types. If you write a literal 0, e.g. Gcc evaluates the expression at compile time (with a different result). The same happens when I compile your code with `gcc -O1` (Gcc can infer that `~n+1` is 0). – mafso Sep 01 '14 at 19:47
  • 2
    @KumarVikramjeet: Because of the last line in my answer. – Lightness Races in Orbit Sep 01 '14 at 19:47
  • 1
    @Mafso I meant why the behavior was consistent in both cases separately. Never mind, I got what u said, thanks! – Kumar Vikramjeet Sep 01 '14 at 19:58
  • Note that left-shifting `~0` by *any* number of bits (except `0`) causes undefined behaviour. – M.M Sep 01 '14 at 22:49
  • @MattMcNabb: Why's that? Cos no unsigned representation? – Lightness Races in Orbit Sep 01 '14 at 22:55
  • @LightnessRacesInOrbit `~0` is negative, and left-shifting negative values causes UB (6.5.7/4). Actually shifting by `0` bits is also UB, there's no exception stated for that case. – M.M Sep 01 '14 at 22:57