gcc options: -fsigned-char

A guide to understanding and using the -fsigned-char and -funsigned-char GCC options to control the signedness of plain char.
April 2, 2026

gcc options: -fsigned-char

Reqruies
  • Compiler: gcc 2.8 or later
If you use char without any compiler options, is this type signed or unsigned?
The result depends on the architecture and the compiler.
Many developers often write code assuming that char is signed char.
However, this habit is very dangerous as it can cause unexpected behavior depending on the architecture or compiler options.
It is a coding habit that must be avoided, especially if you need to write architecture-independent code.
The GCC compiler has options (classified as C Dialect Options in the GCC documentation) to determine whether to treat char as signed or unsigned.

Options

-fsigned-char, -funsigned-char, -fno-signed-char, -fno-unsigned-char
There are several options, but ultimately they are used with the following two meanings:
Treat char as signed char: -fsigned-char, -fno-unsigned-char
Treat char as unsigned char: -funsigned-char, -fno-signed-char
These are very simple GCC options and are explained in detail in the GCC documentation.

GCC Documentation

gcc-7.4.0/C-Dialect-Options
Doc

-funsigned-char

Let the type char be unsigned, like unsigned char. Each kind of machine has a default for what char should be. It is either like unsigned char by default or like signed char by default. Ideally, a portable program should always use signed char or unsigned char when it depends on the signedness of an object. But many programs have been written to use plain char 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 of signed char or unsigned char, even though its behavior is always just like one of those two.

While I couldn't find the exact GCC version where this option was first introduced in the official documentation, it can be seen that it was already included in the GCC 2.8.0 release code.
gcc-2.8.0 toplev.c
c
It is difficult to find a clear history in the official release notes, but it seems that the option parsing was added in GCC version 3.1 in the cpp preprocessor source code.
gcc-3.1 cppinit.c
c

Verification

Let's check through the code if the option actually works as intended.
char.c
c
Execution result without option
sh
In the x86_64 environment and with the current compiler, char is being treated as signed char.
Now, let's try adding the -funsigned-char option.
Execution result with -funsigned-char
sh
By adding the -funsigned-char option, you can confirm that char is used as unsigned char.

Architecture

Let's also look at how each architecture handles char by default.
x86_64 - default signed char
bash
aarch64 - default unsigned char
bash
mips64 - default signed char
bash
ppc - default unsigned char
bash

Check with sample code

Here is a sample code to easily check if char is signed or unsigned.
Simple check code
c
Result
sh

Conclusion

In large-scale projects, compiler options can be added or changed globally by the build system, so relying on the default signedness characteristics can lead to unexpected bugs.
In conclusion, rather than relying on compiler options, it is much safer and more desirable to explicitly use signed char or unsigned char instead of char in code where the distinction between signed and unsigned is important.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.