1
(-1L<1U) ? printf("A"):printf("B");    
(-1L<1UL) ? printf("C"):printf("D");    
((short int)-1<1U) ? printf("E"):printf("F");    
((short int)-1<1UL) ? printf("G"):printf("H");    

This piece of code after running in gcc compiler returns back BDEH....i am not able to understand why it is like that.Please someone guide on this.

Rakesh_Kumar
  • 1,442
  • 1
  • 14
  • 30

1 Answers1

6

This is called "usual arithmetic conversions" by the standard and applies whenever two different integer types occur as operands of the same operator.

In essence what is does

  • if the types have different width (more precisely what the standard calls conversion rank) then it converts to the wider type
  • if both types are of same width, besides really weird architectures, the unsigned of them wins

Signed to unsigned conversion of the value -1 with whatever type always results in the highest representable value of the unsigned type.

For line (1) the outcome depends on how wide long and int are. If int is narrower than long, all unsigned values fit in long, and so the conversion stops at long for the RHS. The outcome then is "A". If they are of same width, the conversion continues to unsigned long for both sides and the outcome is "B".

For your special case for short there is also a feature called "integer promotions" that promotes all types that are narrower than int to int. In your lines 3 and 4 you'd have that the expressions on the LHS are first converted to int, which keeps the value unchanged, and then for (3) to unsigned int and for (4) to unsigned long.

According to that my platform (linux, gcc) correctly prints "ADFH" with your code.

The result "BDEH" would occur on a platform that first has long and int of the same width and has the range of unsigned covered by the range of int, that is which for unsigned just ignores the sign bit of int. I didn't know that such platforms still exist.

Some years I wrote a blog post on the anatomy of integer types, which should still be valid.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Maybe on pre-ANSI compilers? – David Ranieri Oct 17 '13 at 07:00
  • So by the logic u said...in line 3 after conversion of short int to int and again to unsigned int, its value should be greater than highest representable value of unsigned type, hence the statement returns false,printing leads to F, but answer is E...how come this discrepency. – Rakesh_Kumar Oct 17 '13 at 07:05
  • @AlterMann, Rakesh says he has a gcc. – Jens Gustedt Oct 17 '13 at 07:16
  • @Rakesh_Kumar, no it is not one bigger, but it is the highest representable value. For the discrepancy, what I say in my last paragraph, that is only allowed if `unsigned` just doesn't use the sign bit of `int`. You should have specified your exact platform in your question, without that we can't say much more. – Jens Gustedt Oct 17 '13 at 07:19
  • 1
    @JensGustedt I suppose your platform is 64 bit where `long` ranks higher than `unsigned`. Hence it prints A for the case 1. Another possibility is "BDFH" if rank(long)==rank(unsigned) (most 32 bit platforms) and unsigned wins. – P.P Oct 17 '13 at 07:42
  • @BlueMoon,, the ranks are always ordered `int < long < long long` so this can't be it. You probably meant that the width of `long` and `int` are the same. Yes this is probably the difference for the A versus B. I'll update. But that wouldn't explain the E versus F. – Jens Gustedt Oct 17 '13 at 08:02
  • @JensGustedt Yes, I should have mentioned width. Sorry. E vs. F is still magical as it doesn't fall under anything. I even checked with ideone that OP claims to be using. But it produces "BDFH" with both ["C" compiler](http://ideone.com/F7xhAp) and ["C99 strict" compiler](http://ideone.com/XdNTBU)(not BDEH as OP says). – P.P Oct 17 '13 at 08:17
  • @BlueMoon, for that you really need a compiler that just masks the sign bit of `int` to represent `unsigned`. The only thing I would know that could produce such a thing nowadays would be some C emulation on top of Java, since there they don't have native `unsigned` types. – Jens Gustedt Oct 17 '13 at 09:19