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
The result depends on the
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
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
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-OptionsDoc-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.cc
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.cc
Verification
Let's check through the code if the option actually works as intended.
char.cc
Execution result without optionsh
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-charsh
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 charbash
aarch64 - default unsigned charbash
mips64 - default signed charbash
ppc - default unsigned charbash
Check with sample code
Here is a sample code to easily check if
char is signed or unsigned.Simple check codec
Resultsh
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.