4

What are the possible situations where would we need a signed char? I guess the only use of this is in conversion of a char quantity to an integer.

Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
  • Possible duplicate of [Is char signed or unsigned by default?](https://stackoverflow.com/questions/2054939/is-char-signed-or-unsigned-by-default) – phuclv Jun 23 '19 at 05:03

6 Answers6

4

If I remember right, a "char" may be signed or unsigned (it depends on the compiler/implementation). If you need an unsigned char you should explicitly ask for it (with "unsigned char") and if you need a signed char you should explicitly ask for it (with "signed char").

A "char" is just a (typically 8-bit) integer. It has nothing to do with characters.

A character could be anything, depending on what you're doing. I prefer using "uint32_t" and Unicode (UTF-32). For crusty old/broken software that uses ASCII, a char is fine (regardless of whether "char" is signed or unsigned). For UTF-8 you'd probably want to use "unsigned char" or "uint8_t".

You might also be tempted to try to use "wchar_t" (and the "wchar.h" header), but there's lots of ways that can go wrong (do some research if you're tempted).

Brendan
  • 35,656
  • 2
  • 39
  • 66
3

The reason why compilers are allowed to make plain char signed is that back in the very early days of the C programming language, every integer type was signed. By the time unsigned types were added to the language, there must already have been too much existing code that did things like store -1 in a char variable as a sentinel value, that it was not feasible to to change the compilers on existing systems such that char was unsigned. There probably wasn't any great pressure for unsigned chars anyway; the early development of C happened on 7-bit ASCII.

As C was ported to platforms where there were 8-bit printable characters (such as IBM mainframes speaking EBCDIC or the PC), compilers there made char unsigned because having a printable character with a negative value would be an even larger portability nightmare than not being able to store -1 in a char. On the other hand, this led to the current situation where portable code cannot make any assumptions about the signedness of char.

hmakholm left over Monica
  • 23,074
  • 3
  • 51
  • 73
2

char is an integer, usually with a width of 8 bits. But because its signedness is implementation defined (ie depends on compiler), it is probably not a good idea to use it for arithmetic. Use unsigned char or signed char instead, or if you want to enforce the width, use uint8_t and int8_t from stdint.h.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • @tony, how comes that you edited my answer to invert its meaning? Using `uint8_t` makes explicit assumptions about the width, in particular if it exists it is implied that `char` a width of 8 bit. Also it would be nice if those who approve such edits (there must have been two who voted for it) read the edits more carefully. – Jens Gustedt Aug 07 '11 at 13:10
  • @I'm not tony, but "making assumptions" usually means you have no hard facts to go by, and are guessing. So his correction more or less meant "if you don't want to guess about width, use int8_t" etc... I would completely rephrase the sentence, since both versions are a bit unclear. "if you want to have a certain width, use fixed size types like int8_t" etc. – Rudy Velthuis Aug 07 '11 at 16:38
0

Inline with what you mentioned, char are 8 bit integer values. You wouldn't strictly need them to be negative for most practical purpose. Since, they must be represented as bits and allow arithmetic operations to be performed on them, they are represented as int. Of course, you have unsigned char also.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
0

In any place where you want to represent a value in the range [-128, 127] an signed char is fit. If you have a struct with many fields that will be instantiated a lot of times it is relevant to keep the data types as small as possible.

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
0

In the code bellow:

signed char c = -1;
printf("%c %d\n", c, c);
c = c >> 1;
printf("%c %d\n", c, c);

The result will be different if you use an unsigned char instead of a signed char (at least, it is on my "AMD Athlon(tm) 64 Processor" with gcc under cygwin). The reason for that is when you right shift an unsigned value, it is padded with zero, and when you do the same with a signed value that is negative, it is padded with one.

Is this useful though, I cannot tell... but this is a situation where the sign of a char matter.

tinman
  • 6,348
  • 1
  • 30
  • 43
jfg956
  • 16,077
  • 4
  • 26
  • 34
  • bit-shift operators on negative values is undefined by the c spec. See 6.5.7 Bitwise shift operators: "5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. **If E1 has a signed type and a negative value, the resulting value is implementation-defined.**" – xaviersjs Aug 14 '15 at 11:00