-2

I am trying to do left shift bit in c.

int a = 32;    
printf("%d\n", ~0 << a);    
printf("%d\n", ~0 << 32);    

So I run above 2 printf()s, the result is different. I use dev-C++. I don't understand why is different. Please help me.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • 1
    What is the output you are seeing on the console? – TomT the Weatherman Apr 24 '13 at 04:00
  • Also http://stackoverflow.com/questions/3394259/weird-behavior-of-right-shift-operator, http://stackoverflow.com/questions/13087816/confused-by-undefined-c-shift-operator-behavior-and-wrapping-pattern-space, http://stackoverflow.com/questions/4330282/what-happens-when-you-bit-shift-beyond-the-end-of-a-variable and so on – AnT stands with Russia Apr 24 '13 at 04:06
  • 1
    Actually, I'm not sure any of those _questions_ are dupes since they don't cover the essence here, which is why there's a difference between variable and constant shift. The answers are related since "undefined behaviour" is the correct answer to them all, but I'm loathe to dupe-close a question unless the actual _question_ is a duplicate. – paxdiablo Apr 24 '13 at 04:11

2 Answers2

6

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.

That's from the C standard. The second you start using 32-bit shifts on a value 32 bits wide, all bets are off.

What's possibly happening is that the compiler is constant folding ~0 << 32 since this can be fully calculated at compile time.

The expression ~0 << a can not be constant folded (unless it's a really clever compiler that can determine a will always be 32).

That may account for any difference but, to be honest, there's nothing in the standard stopping the program from erasing your hard disk or creating a mini black hole in the CPU (other than the market reaction) since undefined behaviour is, well, undefined.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • This is definitely what accounts for the difference because if you compile (on command lilne) with gcc -O1 the result becomes the same. – artem Apr 24 '13 at 04:05
  • Nothing ever stops compilers from generating programs that do those things. If your source code conforms to the standard then such a compiler doesn't, but there's no law of physics that says that implementations must conform ... in fact, there are *no* conforming implementations because they all have bugs. So this talk about "nothing stopping" is logically and conceptually confused. (Your edit helps but, as a former member of the standards committee, I still consider such statements to be silly; it's not what we intended.) – Jim Balter Apr 24 '13 at 04:11
  • Changed to "nothing in the standard". If a compiler does those bad things in response to standards-conforming code, I would argue it's _not_ a C compiler :-) – paxdiablo Apr 24 '13 at 04:13
  • Again, *no* compiler is a **conforming** C compiler. Bother source code and implementations can contain bugs that result in bad things happening ... and both have. Fortunately, bugs in implementations are less common. BTW, a **conforming** compiler that does those bad things in response to non-conforming code is crap; the rationale (unfortunately defunct) that accompanied the standard talked about "quality of implementation". There are lots of things that conforming implementations *could* do that aren't good to do. – Jim Balter Apr 24 '13 at 04:14
  • Jim, I'll make one more comment and leave it there. You seem to be talking in the concrete while I'm being abstract. There probably _is_ no conforming compiler in existence, because of bugs and such, but such a beast _is_ possible, the compiler that obeys all the rules of the standard. The reason why I added that para was to indicate that even _that perfect compiler_ is free to do what it wants if you give it code that invokes undefined behaviour. I'll close by stating that you're almost certainly right, no compiler in existence is 100% faithful to the standard and hope we can leave it there. – paxdiablo Apr 24 '13 at 04:32
0

You're (probably) shifting by >= the amount of bits in a type (likely int is 32 bits on whatever system you're using). This is undefined behaviour - the compiler is allowed to emit code that does anything it wants.

Yuushi
  • 25,132
  • 7
  • 63
  • 81