tags:

views:

80

answers:

8

Hi

I am pretty new to C. I recently came across this piece of code in C:

#include <stdio.h>

int main()
{
        unsigned Abc = 1;
        signed Xyz = -1;

        if(Abc<Xyz)
                printf("Less");
        else
        if(Abc>Xyz)
                printf("Great");
        else
        if(Abc==Xyz)
        printf("Equal");
        return 0;
}

I tried running it and it outputs "Less". How does it work? What is the meaning of unsigned Abc? I could understand unsigned char Abc, but simply unsigned Abc? I am pretty sure Abc is no data type! How(and Why?) does this work?

+1  A: 

The default type in C is int. Therefore unsigned is a synonym for unsigned int.

Singed integers are usually handled using twos complement. This means that the actual value for 1 is 0x0001 and the actual value for -1 is 0xFFFF.

Paul
Lets not forget 25 years of i386...
Matt Joiner
+1  A: 

As far as I know, the signed value gets promoted to an unsigned value and so becomes very large.

Helper Method
+1  A: 

int is the "default" type in C. unsigned Abc means unsigned int Abc just like long L means long int L.

When you have an expression that mixes signed and unsigned ints, the signed ints get automatically converted to unsigned. Most systems use two's complement to store integers, so (unsigned int)(-1) is equal to the largest possible unsigned int.

dan04
+4  A: 

Two things are happening.

  1. The default data type in C in int. Thus you have variables of type signed int and unsigned int.

  2. When and unsigned int and a signed int are used in an expression the signed int is converted to unsigned before the expression is evaluated. This will cause signed(-1) to turn into a very large unsigned number (due to 2's complement representation).

Darron
A: 

unsigned/signed is just short specification for unsigned int/signed int (source), so no, you don't have variable with "no data type"

Nox
+1  A: 

Comparing signed and unsigned types result in undefined behavior. Your program can and will print different results on different platforms.

Please see comments.

Alexandre C.
Can't find the actual link just now, but my understanding is that int promotion (signed to unsigned in this particular case) is well defined. But be that as it may, it's not intuitive to a beginner.
Detmar
@Detmar: ah... hmmm must check the standard. It may be different for C and C++ though. If I recall correctly, nothing (or little?)is told about binary representation of signed integers, that is what makes me think it is UB.
Alexandre C.
-1: No, this is well defined behavior. What is happening, and this is normative in C, is what Darron describes in his answer.
Jens Gustedt
@Jens: Conversion from signed to unsigned is *implementation specific behavior*. Nothing enforces the use of 2-complement.
Alexandre C.
@Alexandre: not at all. Conversion from `signed` to `unsigned` is well defined in the standard. It is done modulo `2^N` where `N` is the width of the unsigned target type. Which comes out to be the two's complement representation of the signed value if it fits in the unsigned. To summarize, no a signed integer is not necessarily in two's complement, but yes a signed that is converted to an unsigned has exactly the same bit pattern as in two's complement representation.
Jens Gustedt
@Jens: Okay, thanks for explaining a rather obscure point of the standard.
Alexandre C.
@Alexandre: took the downvote back. If you think this is obscure, look at conversion the other way round, from unsigned to signed :)
Jens Gustedt
A: 

The signed value will get promoted to unsigned and therefore it will be bigger than 1.

chaitanyavarma
A: 

Add the following line after signed Xyz = -1;

printf("is Abc => %x less than Xyz => %x\n",Abc,Xyz);

and see the result for yourself.

Ibrahim
Even better would be to use `%u` for the formats.
Jens Gustedt