默认情况下字符是有符号的还是无符号的?

在《 C 的完整参考》一书中提到,char在默认情况下是无符号的。

但是我正试图用 GCC 和 VisualStudio 来验证这一点。默认情况下,它将其作为 签了

哪一个是正确的?

116535 次浏览

这本书是错误的。标准没有指定纯 char是签名的还是未签名的。

事实上,该标准定义了三种不同的类型: charsigned charunsigned char。如果你看看 #include <limits.h>,然后再看看 CHAR_MIN,你可以知道简单的 charsigned还是 unsigned(如果 CHAR_MIN小于0或等于0) ,但即使如此,就标准而言,三种类型是不同的

请注意,char在这方面是特殊的。如果将一个变量声明为 int,那么它100% 等效于将其声明为 signed int。对于所有的编译器和体系结构来说都是如此。

作为 阿洛克指出,标准将其留给实现。

对于 gcc,默认值是有符号的,但是您可以使用 -funsigned-char修改它。< b > 注意: 对于 Android NDK 的 gcc,默认值为 unsigned.您还可以使用 -fsigned-char显式地请求有符号字符。

在 MSVC 上,默认值是签名的,但是您可以用 /J修改它。

C99N1256草案 6.2.5/15“类型”对 char类型的有符号性有以下说明:

实现应该定义 char,使其具有与有符号 char 或无符号 char 相同的范围、表示和行为。

还有一个脚注:

<limits.h>中定义的 CHAR_MIN将具有 0SCHAR_MIN值之一,这可以用来区分这两个选项。不管选择了什么,char是一个独立的类型从其他两个,是不兼容的。

根据 Dennis Ritchie 的 C 语言编程书籍(ANSI C 事实上的标准书籍) ,有符号或无符号的普通字符依赖于机器,但可打印字符总是正的。

根据 C 标准,纯字符的符号性是“实现定义的”。

一般来说,实现者会选择在他们的架构上实现效率更高的方法。在 x86系统上,字符通常是有符号的。在手臂系统上,它通常是未签名的(苹果 iOS 是个例外)。

现在,我们知道标准把这个问题留给了实现。

但如何检查类型是 signedunsigned,如 char

我为此编写了一个宏:

#define IS_UNSIGNED(t) ((t)~1 > 0)

并用 gccclangcl进行测试。但我不确定对其他病例是否总是安全的。