Since the nature of a char
in C++ is compiler-dependent when the unsigned
qualifier is not present, is there an argument I could pass on to GCC which would force all char
s to be compiled as unsigned
?

- 378,754
- 76
- 643
- 1,055
-
10I found this out in ten seconds by Googling `gcc force unsigned char` then reading the GCC documentation that comes up. What prevented you from performing this research? – Lightness Races in Orbit Dec 11 '13 at 11:59
-
2@LRO, because you are clearly much quicker than trawling through google... ;) – Nim Dec 11 '13 at 12:01
-
3It's probably better to use `unsigned char` rather than plain `char`. Your program will likely be linked with code that was compiled without `-funsigned-char`. If you depend on unsigned bytes, it's safer to express that in the code rather than in a compiler option. – Keith Thompson Jan 01 '15 at 01:21
-
@Keith -- that is the craziest comment I've read here. A plain text ascii file doesn't know if the bytes are signed or unsigned, let alone memory. Some platforms have char as unsigned by default. The char data type specification was written to not be very particular about the signedness to begin with. – B. Nadolson Aug 12 '15 at 07:07
-
4@B.Nadolson: You must not have read many comments if you think mine is the craziest. The question wasn't about ASCII text files, it was about the type `char`. The type `char` *is* very particular about its signedness. On some implementations it's particularly signed; on others it's particularly unsigned. If the signedness matters, you should use `signed char` or `unsigned char`; that's why they exist. – Keith Thompson Aug 12 '15 at 15:03
5 Answers
The flag you are looking for is -funsigned-char
.
From the documentation:
-funsigned-char
Let the type
char
be unsigned, likeunsigned char
.Each kind of machine has a default for what
char
should be. It is either likeunsigned char
by default or likesigned char
by default.Ideally, a portable program should always use
signed char
orunsigned char
when it depends on the signedness of an object. But many programs have been written to use plainchar
and expect it to be signed, or expect it to be unsigned, depending on the machines they were written for. This option, and its inverse, let you make such a program work with the opposite default.The type
char
is always a distinct type from each ofsigned char
orunsigned char
, even though its behavior is always just like one of those two.
-fsigned-char
Let the type
char
be signed, likesigned char
.Note that this is equivalent to
-fno-unsigned-char
, which is the negative form of-funsigned-char
. Likewise, the option-fno-signed-char
is equivalent to-funsigned-char
.
This only impacts char
; types like wchar_t
are unaffected.

- 378,754
- 76
- 643
- 1,055
-
Can you confirm this flag has no impact on the signedness of `wchar_t`? – Antonio Apr 18 '16 at 13:15
-
-
@Antonio: [Yes](https://coliru.stacked-crooked.com/a/44af632c1b9bf7b2). – Lightness Races in Orbit Oct 06 '19 at 23:39
As the other answers say, gcc's -funsigned-char
option forces plain char
to be unsigned.
But that may not be the best solution to your problem. You want unsigned characters, but by using a compiler-specific option you're encoding that information in the build command (the Makefile, build script, or just the command you type to compile your code). If the semantics of your program depend on having unsigned characters, it's better to record that information in your source code. It's clearer, and it's reduces the chance that someone will build your program incorrectly.
If you want unsigned characters, using unsigned char
. If you want signed characters, use signed char
. If you just want characters, and you're sure your program's behavior doesn't depend on whether they're signed or unsigned (say, if all stored values are in the range 0..127), use char
.

- 254,901
- 44
- 429
- 631
-
Keith I have a question; I would normally agree with the last paragraph of your answer... except... Many POSIX functions have documented interface that uses `char`, for example the ones that read files (with characters in them). OK, now suppose I want to use them but I want to process bit representations of read characters, and only bit representation of `unsigned char` is guaranteed. So in that case, it would seem it would be proper to use `-funsigned-char` . Do you disagree? – Mark Galeck Oct 21 '22 at 06:02
-
1@MarkGaleck Yes, I disagree, though I can see your point. Normally lines of text are made up of `char` values, and if you want to read `unsigned char` values from a file it's rare for the file to be made up of lines (typically it would be a binary file). But if you really need to do that, you can cast a `char*` pointer that points to a line of text and cast it to `unsigned char*`. Remember that `-funsigned-char` doesn't cause the runtime library to treat plain `char` as unsigned; it only affects the code you compile with that option. – Keith Thompson Oct 21 '22 at 07:58
-
ah yes, I see, thank you, yes, I get "records" from files, that are not lines as such, but are `char *` pointers and I know how long after that the record is, yes I will cast them to `unsigned char*` – Mark Galeck Oct 25 '22 at 02:01
-
@MarkGaleck How are you getting these "records"? Would `fread` make more sense? – Keith Thompson Oct 25 '22 at 02:33
-
thank you! I did not know about `fread` :) but well, my records are not of the fixed size, I just know what size to expect at any particular moment, but the sizes vary – Mark Galeck Oct 25 '22 at 04:02
-
@MarkGaleck Well, if you know how big the next record is, you can pass that size as a parameter to `fread`. See also https://stackoverflow.com/a/8589688/827263 – Keith Thompson Oct 25 '22 at 04:45
-
well yes, but the point of `fread` really is so that I can ready many records at once. – Mark Galeck Oct 25 '22 at 06:06
-
@MarkGaleck The point of `fread` is to read however many records you want to read. There's nothing wrong with reading one record at a time. What are you using now? – Keith Thompson Oct 25 '22 at 18:29
-
1I see, sorry, ... I got the gist of `fread` wrong, it is like `read` except for `FILE *`. Well OK, I generally work with file descriptors. Anyway, after talking to you, I went and checked carefully, and found that I can just use `mmap` all the time. So that solves the problem, I don't really need `funsigned-char`. But it was good to learn stuff from you. Thank you. – Mark Galeck Oct 27 '22 at 08:57
Not enough reputation to comment @Keith's answer.
The main reason I see to use -funsigned-char
or -fsigned-char
is when you want the following code
printf("%d\n",'\x80');
to display either -128
or 128
.
The comment about not relying on specific compilation settings is valid but here it is a bit simplifying reality. The main problem is that C leaves some part of the language to the implementation for efficiency reason, and usually you want to tune that implementation to suit best your application. In my opinion a professional developer should always go through all compiler flags and select the best for his needs. If you rely on some specific settings, your unit tests will of course cover that case, or assert it. If you port an application, you will look into the compilation settings of the original port.

- 175
- 2
- 9
-
-
I see. I'm not familiar with that construction. Doesn't seem grammatical to me, either. What does it mean? – Lightness Races in Orbit Mar 06 '18 at 15:55
-
After some googling, doing s/to/in/ might be clearer for you. Turns out I was using this for years but is incorrect indeed. Thanks for pointing it out! – fuujuhi Mar 06 '18 at 16:00
-
I had to check to confirm that that would even work, because character constants are of type `int`, but yes, `-funsigned-char` or `-fsigned-char` does affect the value of `'\x80'`. But if I cared, I'd just cast the constant to `signed char` or `unsigned char` rather than using a compiler option. Remember that those options apply only to code compiled with the options; library code will still use the implementation's choice of signedness for plain `char`. The options are there to cater to existing code that was written with unwarranted assumptions. – Keith Thompson Oct 21 '22 at 19:08