Serious 'char' compiler problem.

I have been writing a vector clock program for a friend and have been using the 'char' datatype to store the coordinates for a vector font so as to reduce the storage area, especially as the range for the coordinates is only +/- 34.
But whenever a 'char' is converted to any other signed datatype it's sign is ignored.
For example:

char ch=-2;
if (ch == -2) .........

will always fail as the value compared to '-2' is 254, this is fine for a 'byte' but completely wrong for a 'char'!

Works for me...

char ch=-2;

void setup( void )
{
  Serial.begin( 115200 );
}

void loop( void )
{
  if (ch == -2)
    Serial.println( "GOOD" );
  else
    Serial.println( "BAD" );
    
  delay( 1000 );
}
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD

Thanks for your reply. I have just pasted your code into my dev setup (Arduino 1.5.4) and fired it up on my Due board and I get:
BAD
BAD
BAD
BAD
BAD
BAD
BAD

So it seems like it could be a problem with this latest beta which I have to use for the Due!

If you need 'char' to be signed, you should be explicit. An implementation is free to make plain 'char' signed or unsigned. Instead you should use either the signed char type, or the int8_t type. For embedded systems, I tend to prefer being explicit in terms of sizes (int is 16-bits on AVRs and 32-bits on ARMs).

Tried adding 'signed' and it does solve this problem 8)

I have been a programmer for over 30 years and this is the first 'C' compiler I have used that does not treat a 'char' as signed.
In fact this is a copy of the section from the online reference:-

The char datatype is a signed type, meaning that it encodes numbers from -128 to 127. For an unsigned, one-byte (8 bit) data type, use the byte data type.

Anyway, many thanks for your help, I should have thought of trying that for myself!

GadgetFreak:
Tried adding 'signed' and it does solve this problem 8)

I have been a programmer for over 30 years and this is the first 'C' compiler I have used that does not treat a 'char' as signed.
In fact this is a copy of the section from the online reference:-

The char datatype is a signed type, meaning that it encodes numbers from -128 to 127. For an unsigned, one-byte (8 bit) data type, use the byte data type.

Anyway, many thanks for your help, I should have thought of trying that for myself!

BTW, your reference is wrong. It may be true of particular implementations, but the definition of C has always left the signed-ness of char up to the implementation (whether right shift sign extends or zero extends is another). I was on the original ANSI X3J11 committee that produced the C89 and C90 standards (I dropped mid-way before the C99 standard came out), and implemented a C compiler before the standards process began, so in this one case, I know what I'm talking about.

There are various compilers out there that default to unsigned chars. Lets see, the PowerPC and ARM GCC compilers both default to char being unsigned, as did the Data General MV/Eclipse compiler I wrote many years ago. So, if you use a Due, it likely defaults to unsigned char's unless the IDE uses the -fsigned-char option.

In terms of holding characters, it should have been unsigned so that you could use it as an index. However, C was developed on DEC hardware (PDP-7 and then PDP-11) that only had load byte with sign extension, and it was developed at a time in the US which at the time used the 7-bit encoding for characters, so all of the printable characters were positive even if bytes were signed. When the world went to 8-bit encoding, many of the additional characters in the European languages had the high bit set. This means if you wanted to index into a table, you now had to explicitly lop off the upper bits. In addition, the getchar/getc library routines need to return an out of band character to represent EOF, and they return -1.

I met up with Dennis Ritchie (main inventor of C) many years ago, and he said that if he could go back in time and amend C with the benefit of hindsight, one of the changes he would have made would have been to decree that 'char' always be 0..255. It is important to have an 8-bit signed data type, but it shouldn't have been called 'char'.

using the 'char' datatype to store the coordinates for a vector font so as to reduce the storage area, especially as the range for the coordinates is only +/- 34.

A good place to use "int8_t" instead of "char"
It's a shame that it's such a beginner-unfriendly name.

Wow, many thanks for the history lesson Michael.
The first computer I used was a PDP11/25, but the first one I owned was a VIC-20.
My first 9 years programming was in 6502, 6809, Z80 & 68000 assembler, in those days I always thought 'C' was lame :*
I actually have a copy of Dennis Ritchie's book somewhere.
Still it seems that some versions of the Arduino environment treat 'char' as signed and certainly 1.5.4 treats them as unsigned.
Perhaps they should amend the online reference so it at least matches their compiler.

Given that "char" is not the same as "unsigned char" or "signed char",
(it gets special/different treatment from both of those regardless of the implementations default signed-ness of char),
the best thing to do is never use "char" for anything but real characters.

There is another recent thread on this here:
http://forum.arduino.cc//index.php?topic=195033.0

--- bill