472,789 Members | 1,312 Online

# unexpected output

Below code outputs garbage value. any idea why so?
Expand|Select|Wrap|Line Numbers
1. unsigned variable1=1;
2. int variable2=-4;
3. printf("%u",variable1+variable2);
4.
Mar 1 '20 #1
11 12662
dev7060
626 Expert 512MB
Below code outputs garbage value. any idea why so?
What garbage value? Negative numbers are represented in 2's complement form.
Mar 1 '20 #2
Thanks for replying. the outputs says 4294967293 which is nowhere near what i interpret.
Mar 1 '20 #3
dev7060
626 Expert 512MB
You gotta think the way the machine is processing stuff.

Binary of 4 = 100 , 1's complement representation: 011, 2's complement representation: 100

But, sizeof(int) = 4 bytes = 32 bits which means the machine is processing numbers with respect to 32 bits.

Therefore, -4 is represented as 11111111 11111111 11111111 11111100

which is equivalent to (2^32-1)-3

Hence, variable1+variable2 means ((2^32-1)-3)+1 which results in 4294967293 and is not a garbage value.
Mar 1 '20 #4
donbock
2,426 Expert 2GB
One of the arguments to printf() is an expression that adds an unsigned int variable to an int variable. The compiler uses the usual arithmetic conversions to resolve this type discrepancy before evaluating the expression: the int variable is implicitly cast to unsigned int.

dev7060's post explains the rest.
Mar 8 '20 #5
Hi thanks to both. i understand it now :)
Mar 15 '20 #6
int to unsigned int covert by compiler.
Jul 8 '20 #7
donbock
2,426 Expert 2GB
My earlier reply was incomplete. Even if both variable1 and variable2 were ints (making the argument expression int), the %u conversion specifier still causes the argument value to be converted to unsigned int inside printf().

To print the expected value of -3:
1. Declare variable1 as int.
2. Change %u to %d.
Jul 8 '20 #8
Banfa
9,065 Expert Mod 8TB
An important point here is that there is no relation between the format string and what you place after the format string, some modern compilers check during compilation that what is in the string matches what comes afterwards but the actual code produced doesn't.

You pass a string and then you place some data on the stack by putting parameters after it. This follows some built in rules about default data types (i.e. all integer types smaller than an int are promoted to an int before being placed on the stack and floats are promoted to doubles).

So I can write

Expand|Select|Wrap|Line Numbers
1.     printf("Number: %d\n", "Hello World");
and the computer will just give it a go, on my computer outputting

Expand|Select|Wrap|Line Numbers
1. Number: 4210688
Jul 9 '20 #9
donbock
2,426 Expert 2GB
In the old days, a common source of bugs in C was from argument type mismatches between a function call and the function definition. For example, passing a double when you call the function but the function itself expected an int. The introduction of function prototypes with ANSI C in 1989 made that kind of bug much less common -- to the point where it may not occur to you to even look for it. However it can still occur.

For example, the function prototype for printf is:
Expand|Select|Wrap|Line Numbers
1. int printf(const char *fmt, …);
Dot-dot-dot tells the compiler to allow any number of parameters to follow and to allow them to be of any type. Dot-dot-dot is why the compiler doesn't notice when you pass an argument to printf that is not compatible with the format string.

Dot-dot-dot is a time machine that takes you back to 1975.
Jul 9 '20 #10
AjayGohil
83 64KB
Hi,

%u is used to print unsingned integer. so variable2is Implicitly converted to unsigned integer and for -4 it is 4294967292 and then add to 1 so ans is 4294967293.
Sep 9 '20 #11
sara999898x
1 Bit
I had the same doubt. Thanks so much.
Jan 13 '23 #12