tags:

views:

310

answers:

2

I have the following code and it seems to me that it should always enter the true part of the if statement but, beyond 120, it appears to start executing the else clause. Why is that happening?

char x;
for (i=0;i<256;i+=10) {
    x=i;
    if (x==i)
        printf("%d true\n",i);
    else 
        printf("%d false\n",i);
}

The output is:

0 true
10 true
: all numbers from 20 to 100 are true
110 true
120 true
130 false
140 false
: all numbers from 150 to 230 are false
240 false
250 false
+12  A: 

Your compiler probably uses an signed char by default when you use the char keyword. The range of a signed char is usually -128 to 127, whereas the range of an int is far greater. More esoteric hardware beyond the typical desktop PC may use other values.

James Morris
That's almost certainly correct for this specific case but I'd like to see it made clear that is _is_ for this specific case. Nothing in the C standard mandates an 8-bit char, nor does it guarantee that an integer is bigger than a char. In addition, I think you meant "range of a _signed_ char is -128 to ...".
paxdiablo
Actually, to avoid any ambiguity, C99 mandates that a char must be *at least* 8 bit (5.2.4.2.1), and it does guarantee that an `int` can contain all values from -32767 to +32767. The statement "the range of an int is far greater than -128..127" is technically true.
Pascal Cuoq
@paxdiablo Thanks, have edited to what I actually meant to say. Yes it's quite easy to assume 8-bit chars. I did, but was grimly aware it may not always be so. I decided these complications were unnecessary at this stage of the op's skill level - and I was going for the quick ++rep fix ;-)
James Morris
@James: Not to mention that the observed behavior strongly suggests 8-bit `char`s, `signed` by default (or is that a requirement in C99?).
David Thornley
@David `char` is still either `signed` or `unsigned` by default as of C99.
Pascal Cuoq
+12  A: 

It's because you are using a signed char and presumably an integer.

The char is overflowing when it reaches 130 (it becomes 130 - 256) but the integer does not overflow. 130 - 256 != 130.

A simple change fixes it so that the result is always true - just add unsigned on the first line:

unsigned char x;
for (int i=0;i<256;i+=10)
{
    x=i;
    if (x==i)
        printf("%d true\n",i);
    else 
        printf("%d false\n",i);
}
Mark Byers
And if the example code did not take steps of size 10 then it would have been much more obvious what was going on because it would have happened at the 127/128 boundary.
nategoose