Integral promotion rules

N

Noob

Hello,

I wrote the following toy program, expecting it would
NOT print anything ("expecting the unexpected").

#include <stdio.h>
int main(void)
{
int i;
unsigned char t = 250;
for (i = 0; i < 10; ++i) if (++t == 0) puts("WRAP");
return 0;
}

(On my system, CHAR_BIT = 8)

I thought that because of integral promotion rules, the value
of ++t was promoted to type int.

So t would reach 255, then the next increment would evaluate
to 256 (type int), since 256 != 0 : no output, and the value
stored back to t is 0 (256 mod 256).

What did I miss? (misunderstand)

Regards.
 
J

James Kuyper

Hello,

I wrote the following toy program, expecting it would
NOT print anything ("expecting the unexpected").

#include <stdio.h>
int main(void)
{
int i;
unsigned char t = 250;
for (i = 0; i < 10; ++i) if (++t == 0) puts("WRAP");
return 0;
}

(On my system, CHAR_BIT = 8)

I thought that because of integral promotion rules, the value
of ++t was promoted to type int.

So t would reach 255, then the next increment would evaluate
to 256 (type int), since 256 != 0 : no output, and the value
stored back to t is 0 (256 mod 256).

What did I miss? (misunderstand)

"The result is the new value of the operand after incrementation."
(6.5.3.1p2). In this case, the operand is 't', and it's value after
assignment is 0; not 256, so the final result is also 0.
 
B

Ben Bacarisse

Noob said:
I wrote the following toy program, expecting it would
NOT print anything ("expecting the unexpected").

#include <stdio.h>
int main(void)
{
int i;
unsigned char t = 250;
for (i = 0; i < 10; ++i) if (++t == 0) puts("WRAP");
return 0;
}

(On my system, CHAR_BIT = 8)

I thought that because of integral promotion rules, the value
of ++t was promoted to type int.

It is. The definition of == mandates "the usual arithmetic conversions"
when both operands have arithmetic types, but it is, as you state, the
value of ++t that is promoted.

The specification of ++ hands off all the hard work to the specification
of += and that, in turn, refers to plain + and =, but before washing its
hands of the matter altogether, it states that the value of the
expression is the new value of the operand, and that must be in the
range 0 to 255 in this case. (In fact, that clause looks redundant
since the value of the assignment is that of the new value of the left
operand anyway).
So t would reach 255, then the next increment would evaluate
to 256 (type int), since 256 != 0 : no output, and the value
stored back to t is 0 (256 mod 256).

In terms of types, conversions, constraints and so on, ++t is the same
as t = t + 1 but with t evaluated only once. It's value will be the new
value of t.

So when t == 255, it is promoted to int as part of the usual arithmetic
conversions in preparation for adding one. One is added to give 256,
and the result is assigned back to t. This converts the int value 256
to unsigned char using the modulo UCHAR_MAX+1 rule. The result is zero.
That zero becomes the result of ++t, and it is that zero that is finally
promoted in preparation for the == test.
What did I miss? (misunderstand)

Actually, not much. The value of ++t is promoted, but the value is that
of t after the assignment.
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top