int main()
{
unsigned char i=255,j=1;
printf("%d\n",i+j);
}
The output of above code is 256.
Why is there no wrapping ?
Because the argument to printf is promoted to int. That's what happens
to unsigned char when passed to a variadic function.
Compare this with:
#include<stdio.h>
void f( unsigned char i )
{
printf("%d\n",i);
}
int main()
{
unsigned char i=255,j=1;
f(i+j);
}
Where there isn't any promotion.
--
Ian Collins
Thanks Collins.
But I am really confused about when and how to apply these promotions
and conversions.
I mean how to know where we have to apply certain conversions?
There is a promotion *prior* to adding i and j. Both are either promoted to
int or unsigned int, depending on whether on your implementation "int" can
store all possible values of "unsigned char" (called "usual arithmetical
conversions). If that's the case, both operands become "int", and then are
added together, and the result is guaranteed not to overflow (because
INT_MAX is at least 2^15-1).
This does not have to do with promotion of arguments to printf, since if it
would wrap around during addition and then promoted (called "default
argument promotions"), we would pass 0 instead of 256.
I still couldn't get the answer of my second question.
Is there any article which specifies all conditions for promotions and
conversions.
You would have to read the Standard if you wanna know for sure. It's not
that difficult to read.
But In standard, it's all scattered.
For the case in point, you'd look up the description of the
additive operators, and you'd find (in 6.5.6) "If both operands
have arithmetic type, the usual arithmetic conversions are performed
on them." Other operators are described similarly -- but often not
identically, since the rules for different operators are not all
exactly alike. For example, some operators apply the more limited
"integer promotions" instead of the full-blown "usual arithmetic
conversions."
6.3 describes the various kinds of conversions in one place,
so the rest of the Standard can just refer to them by name. It
seems to me a logical arrangement -- certainly clearer than
trying to write a section describing "All The Circumstances That
Cause Conversions." In the current arrangement, for example,
you can read about calls to variable-argument functions and learn
that the "..." arguments obey different conversion rules than the
fixed arguments. In an "All Conversions In One Place" arrangement,
the description of the function call would say "These are the
arguments" and the fact that some are converted differently than
others would be in a section fifty pages away.
--
Eric Sosman
eso...@ieee-dot-org.invalid
Answer: It hasn't much to do with printf specifically. ALL arithmetic
promotes at least as far as int. So if you add two unsigned chars, they
are both promoted to int and the result is their sum as an int. If you
then pass that as a function argument to a function expecting unsigned
char, it's roughly as though you'd assigned the value to an unsigned char
and passed that. But printf is variadic, so it can't downgrade, so it
promotes all integer-type arguments at least as far as int, and that's
what gets passed in.
-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
sizeof(i+j) == sizeof(int)
/* BEGIN new.c */
#include <stdio.h>
int main(void)
{
unsigned char i=255,j=1;
const int promotion = sizeof(i+j) == sizeof(int);
if (promotion) {
puts("sizeof(i+j) == sizeof(int)");
}
return 0;
}
/* END new.c */
--
pete