Wrapping in unsigned char

H

happy

#include<stdio.h>

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 ?
 
I

Ian Collins

happy said:
#include<stdio.h>

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.
 
H

happy

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.

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?
 
J

Johannes Schaub (litb)

happy said:
#include<stdio.h>

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 ?

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.
 
S

Stefan Ram

Ian Collins said:
Because the argument to printf is promoted to int.

This can not be the real reason, because this conversion
only happens after the sum was already calculated.

The point is that the type of the sum - even outside
of printf - is larger than unsigned char, at least
for the C implementation I used to run this program:

#include <stdio.h>

int main( void )
{ unsigned char const i = 255;
unsigned char const j = 1;
int const is = sizeof i;
int const ijs = sizeof( i + j );
printf( "%d\n", is );
printf( "%d\n", ijs ); }

/* prints
1
4
*/

But where in ISO/IEC 9899:1999 (E) is the type of
"i + j" specified?
 
S

Stefan Ram

But where in ISO/IEC 9899:1999 (E) is the type of
"i + j" specified?

Oh, now I see:

It seems to be this sentence:

»the integer promotions are performed on both operands.«

in 6.3.1.8#1 of ISO/IEC 9899:1999 (E).
 
H

happy

  Oh, now I see:

  It seems to be this sentence:

      »the integer promotions are performed on both operands.«

  in 6.3.1.8#1 of ISO/IEC 9899:1999 (E).

I still couldn't get the answer of my second question.
Is there any article which specifies all conditions for promotions and
conversions.
 
J

Johannes Schaub (litb)

happy said:
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.
 
H

happy

You would have to read the Standard if you wanna know for sure. It's not
that difficult to read.- Hide quoted text -

- Show quoted text -

But In standard, it's all scattered.
 
E

Eric Sosman

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.
 
S

Seebs

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?

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top