In the book "Complete Reference of C" it is mentioned that char
is by default unsigned.
But I am trying to verify this with GCC as well as Visual Studio. It is taking it as signed by default.
Which one is correct?
In the book "Complete Reference of C" it is mentioned that char
is by default unsigned.
But I am trying to verify this with GCC as well as Visual Studio. It is taking it as signed by default.
Which one is correct?
The book is wrong. The standard does not specify if plain char
is signed or unsigned.
In fact, the standard defines three distinct types: char
, signed char
, and unsigned char
. If you #include <limits.h>
and then look at CHAR_MIN
, you can find out if plain char
is signed
or unsigned
(if CHAR_MIN
is less than 0 or equal to 0), but even then, the three types are distinct as far as the standard is concerned.
Do note that char
is special in this way. If you declare a variable as int
it is 100% equivalent to declaring it as signed int
. This is always true for all compilers and architectures.
int
means signed int
always, right? Apart from char
, what other datatypes have the same confusion in C
? –
Combustion char
is the only type that can be signed or unsigned. int
is equivalent to signed int
for example. –
Barrier int
is signed or unsigned. –
Rosalba char
as unsigned or refuse compilation if it can't do that"? I understand that the standard must allow for the existence of different dialects of C, but if there's no standard way to say that whether 0xFFFF+1
should yield 0u
or 65536, then I would posit that such an expression should be considered meaningless in "standard C". –
Forespent #if CHAR_MIN < 0
... #error "Plain char is signed"
... #endif
–
Rosalba char
as unsigned or refuse compilation of it can't", compilers would be allowed to treat such directives as static assertions, but could also use them to instead control behavior. If the term "implementation-defined" can stretch far enough to let a compiler define a sequence of configuration settings it will try in sequence to see if any will work, a compiler could use "static assert" as a configuration directive, but that seems really hokey and unlikely. –
Forespent signed char
and unsigned char
; and char
is just an alias for one of those. Standard just does not say which one. Therefore in C++ you need explicit casting between them, in C you do not. –
Masterson char
, 'signed char', and unsigned char
are distinct types: "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." –
Engelhart As Alok points out, the standard leaves that up to the implementation.
For gcc, the default is signed, but you can modify that with -funsigned-char
. note: for gcc in Android NDK, the default is unsigned. You can also explicitly ask for signed characters with -fsigned-char
.
On MSVC, the default is signed but you can modify that with /J
.
C99 N1256 draft 6.2.5/15 "Types" has this to say about the signed-ness of type char
:
The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.
and in a footnote:
CHAR_MIN
, defined in<limits.h>
, will have one of the values0
orSCHAR_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.
According to The C Programming Language book by Dennis Ritchie which is the de-facto standard book for ANSI C, plain chars either signed or unsigned are machine dependent, but printable characters are always positive.
According to the C standard the signedness of plain char is "implementation defined".
In general implementors chose whichever was more efficient to implement on their architecture. On x86 systems char is generally signed. On arm systems it is generally unsigned (Apple iOS is an exception).
Now, we known the standard leaves that up to the implementation.
But how to check a type is signed
or unsigned
, such as char
?
I wrote a macro to do this:
#define IS_UNSIGNED(t) ((t)~1 > 0)
and test it with gcc
, clang
, and cl
. But I do not sure it's always safe for other cases.
© 2022 - 2024 — McMap. All rights reserved.
char
can be unsigned, as a rule of thumb use anint
to read a value usinggetchar()
, which might returnEOF
.EOF
is usually defined as-1
or other negative value, which storing in anunsigned
is not what you want. Here's the declaration:extern int getchar();
BTW, this recommendation comes also from "C: A Reference Manual" book. – Cruzcruzadochar
case, you'd have to useint
to store the return value. – Loireatlantique