MM1
MM1

Reputation: 944

Clarifications about unsigned type in C

Hi I'm currently learning C and there's something that I quite don't understand. First of all I was told that if I did this:

unsigned int c2 = -1;
printf("c2 = %u\n", c2);

It would output 255, according to this table:

table

But I get a weird result: c2 = 4294967295

Now what's weirder is that this works:

unsigned char c2 = -1;
printf("c2 = %d\n", c2);

But I don't understand because since a char is, well, a char why does it even print anything? Since the specifier here is %d and not %u as it should be for unsigned types.

Upvotes: 4

Views: 810

Answers (3)

Marco Bonelli
Marco Bonelli

Reputation: 69276

The following code:

unsigned int c2 = -1;
printf("c2 = %u\n", c2);

Will never print 255. The table you are looking at is referring to an unsigned integer of 8 bits. An int in C needs to be at least 16 bits in order to comply with the C standard (UINT_MAX defined as 2^16-1 in paragraph §5.2.4.2.1, page 22 here). Therefore the value you will see is going to be a much larger number than 255. The most common implementations use 32 bits for an int, and in that case you'll see 4294967295 (2^32 - 1).

You can check how many bits are used for any kind of variable on your system by doing sizeof(type_or_variable) * CHAR_BIT (CHAR_BIT is defined in limits.h and represents the number of bits per byte, which is again most of the times 8).

The correct code to obtain 255 as output is:

unsigned char c = -1;
printf("c = %hhu\n", c);

Where the hh prefix specifier means (from man 3 printf):

hh: A following integer conversion corresponds to a signed char or unsigned char argument, or a following n conversion corresponds to a pointer to a signed char argument.

Anything else is just implementation defined or even worse undefined behavior.

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 310910

In this declaration

unsigned char c2 = -1;

the internal representation of -1 is truncated to one byte and interpreted as unsigned char. That is all bits of the object c2 are set.

In this call

printf("c2 = %d\n", c2);

the argument that has the type unsigned char is promoted to the type int preserving its value that is 255. This value is outputted as an integer.

Is this declaration

unsigned int c2 = -1;

there is no truncation. The integer value -1 that usually occupies 4 bytes (according to the size of the type int) is interpreted as an unsigned value with all bits set.

So in this call

printf("c2 = %u\n", c2);

there is outputted the maximum value of the type unsigned int. It is the maximum value because all bits in the internal representation are set. The conversion from signed integer type to a larger unsigned integer type preserve the sign propagating it to the width of the unsigned integer object.

Upvotes: 1

Saif Faidi
Saif Faidi

Reputation: 529

In C integer can have multiple representations, so multiple storage sizes and value ranges refer to the table below for more details.

enter image description here

Upvotes: 0

Related Questions