在《 C 的完整参考》一书中提到,char在默认情况下是无符号的。
char
但是我正试图用 GCC 和 VisualStudio 来验证这一点。默认情况下,它将其作为 签了。
哪一个是正确的?
这本书是错误的。标准没有指定纯 char是签名的还是未签名的。
事实上,该标准定义了三种不同的类型: char、 signed char和 unsigned char。如果你看看 #include <limits.h>,然后再看看 CHAR_MIN,你可以知道简单的 char是 signed还是 unsigned(如果 CHAR_MIN小于0或等于0) ,但即使如此,就标准而言,三种类型是不同的。
signed char
unsigned char
#include <limits.h>
CHAR_MIN
signed
unsigned
请注意,char在这方面是特殊的。如果将一个变量声明为 int,那么它100% 等效于将其声明为 signed int。对于所有的编译器和体系结构来说都是如此。
int
signed int
作为 阿洛克指出,标准将其留给实现。
对于 gcc,默认值是有符号的,但是您可以使用 -funsigned-char修改它。< b > 注意: 对于 Android NDK 的 gcc,默认值为 unsigned.您还可以使用 -fsigned-char显式地请求有符号字符。
-funsigned-char
-fsigned-char
在 MSVC 上,默认值是签名的,但是您可以用 /J修改它。
/J
C99N1256草案 6.2.5/15“类型”对 char类型的有符号性有以下说明:
实现应该定义 char,使其具有与有符号 char 或无符号 char 相同的范围、表示和行为。
还有一个脚注:
在 <limits.h>中定义的 CHAR_MIN将具有 0或 SCHAR_MIN值之一,这可以用来区分这两个选项。不管选择了什么,char是一个独立的类型从其他两个,是不兼容的。
<limits.h>
0
SCHAR_MIN
根据 Dennis Ritchie 的 C 语言编程书籍(ANSI C 事实上的标准书籍) ,有符号或无符号的普通字符依赖于机器,但可打印字符总是正的。
根据 C 标准,纯字符的符号性是“实现定义的”。
一般来说,实现者会选择在他们的架构上实现效率更高的方法。在 x86系统上,字符通常是有符号的。在手臂系统上,它通常是未签名的(苹果 iOS 是个例外)。
现在,我们知道标准把这个问题留给了实现。
但如何检查类型是 signed或 unsigned,如 char?
我为此编写了一个宏:
#define IS_UNSIGNED(t) ((t)~1 > 0)
并用 gcc、 clang和 cl进行测试。但我不确定对其他病例是否总是安全的。
gcc
clang
cl