-1

I was looking at the data types at the link data type

It is written as char type is 1 byte having a range -128 to 127 or 0 to 255.

How can this possible? By default char means signed right. enter image description here

Edit: There is another question Whats wrong with this C code?. But it is not same question. Title says what is wrong with this code and search will not list this answer easily. One has to analyse the question fully to understand the issue.

Edit: After looking at several answers and comments, I got another doubt. Strings within double quotes are treated as char. I get warnings if I pass double quoted strings to a function having parameter of type signed char. Also itoa and many other library functions make use of char type parameter and not signed char. Ofcourse typecasting will avoid this problem. So what is the best parameter type for functions manipulating null terminated strings(for example LCD display related functions)? Use signed char or unsigned char (since char is implementation defined, it may not be portable I guess)

Community
  • 1
  • 1
Rajesh
  • 1,085
  • 1
  • 12
  • 25

3 Answers3

5

char "has the same representation and alignment as either signed char or unsigned char, but is always a distinct type".

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
5

char has implementation-defined signedness. Meaning that one compiler can chose to implement it as signed and another as unsigned.

This is the reason why you should never use the char type for storing numbers. A better type to use for such is uint8_t.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Or use `signed char` or `unsigned char` rather than the default `char`. – John Bollinger Feb 24 '17 at 14:01
  • 1
    @JohnBollinger Or better yet, `uint_fast8_t`. – Lundin Feb 24 '17 at 14:06
  • Interesting and one more weakness of C which can contribute to bugs. Any compiler that considers it as unsigned char? I used few compilers and and it is signed. – Rajesh Feb 24 '17 at 14:11
  • @Rajesh Almost every embedded systems C compiler implement it as unsigned char. It is true that this is a well-known flaw of the C language. The reason it is implementation-defined is backwards-compatibility. – Lundin Feb 24 '17 at 14:15
  • Use `int` or `unsigned int`, unless you really have a space limitation or need a specific width. – too honest for this site Feb 24 '17 at 14:32
  • @Rajesh: How many **different** platforms do you know? The majority of 32 and 64 bit platforms uses unsigned `char`: ARM. Simple reason is that early ARM instruction set had no 8-bit sign-extend load from memory, only zero-extend. In general, using a signed type for a character variable is questionable at best. The string functions in the standard library treat them as unsigned, although they take a `char` for legacy reasons. – too honest for this site Feb 24 '17 at 14:34
  • @Olaf Except where the standard library quite often treats them as `int`, but that's another story :) – Lundin Feb 24 '17 at 15:22
  • @Lundin: You mean integer promotions? These are one reason to use `int` or `unsigned` by default. (`size_t` is often fine, too). `uint_fast8_t` can very well result in an `unsigned int` (and is quite useless). – too honest for this site Feb 24 '17 at 15:50
  • @Olaf No I mean that many C standard library functions dealing with characters tend to have an `int` as parameter. This is partially because [pre-standard library functions used implicit int as parameter](http://stackoverflow.com/questions/2394011/why-does-strchr-take-an-int-for-the-char-to-be-found), partially because many of those functions need to deal with EOF. – Lundin Feb 27 '17 at 09:27
2

No, it doesn't mean signed char by default. According to the C standard, a char is a distinct type from both signed and unsigned chars, that merely behaves like one of the other two.

n1570/6.2.5p15

The three types char, signed char, and unsigned char are collectively called the character types. The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.

And in a note to the above paragraph:

CHAR_MIN, defined in <limits.h>, will have one of the values 0 or SCHAR_MIN, and this can be used to distinguish the two options. Irrespective of the choice made, char is a separate type from the other two and is not compatible with either.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 1
    In another answer earlier today, I actually made a little example demonstrating this: I implemented a way to check for equality of types, [here](http://stackoverflow.com/a/42437022/584518). As we can see in the example code, C did not consider `char` to be equal to neither `signed char` nor `unsigned char`, even though it must have the same representation as either of those types. – Lundin Feb 24 '17 at 14:05
  • I am using Mingw. I assigned a value of 128 to char type variable and the result was -128 when I printed using %d. Does it not mean that default is signed? – Rajesh Feb 24 '17 at 14:05
  • 1
    @Rajesh When you assign 128 to a `char` which can hold a maximum of 127, the value 128 will get converted to a signed value. In addition, `printf` will implicitly promote the passed type to `int`. Similar issues were discussed [here](http://stackoverflow.com/questions/42362568/why-does-my-test-of-sign-always-report-negative) – Lundin Feb 24 '17 at 14:10