在“C 的完整参考”一书中提到,char默认情况下它是无符号的。
但我试图用 GCC 和 Visual Studio 来验证这一点。默认情况下将其视为已签名。
哪一个是正确的?
书错了。该标准没有指定 plainchar是有符号还是无符号。
事实上,该标准定义了三种不同的类型:char、signed char和unsigned char。如果你#include <limits.h>再看CHAR_MIN,你可以发现 plainchar是signedor unsigned(如果CHAR_MIN小于 0 或等于 0),但即便如此,就标准而言,这三种类型是不同的。
请注意,char这种方式很特别。如果将变量声明int为 100% 等同于将其声明为signed int. 这对于所有编译器和架构都是如此。
正如Alok 指出的那样,标准将其留给实施。
对于 gcc,默认是签名的,但您可以使用-funsigned-char. 注意:对于 Android NDK 中的 gcc,默认为 unsigned。您还可以使用 . 明确要求签名字符-fsigned-char。
在 MSVC 上,默认已签名,但您可以使用/J.
C99 N1256 草案6.2.5/15“类型”对 type 的签名有这样的说法char:
实现应将 char 定义为与有符号字符或无符号字符具有相同的范围、表示和行为。
并在脚注中:
CHAR_MIN,在 中定义<limits.h>,将具有值0或之一SCHAR_MIN,这可用于区分这两个选项。无论做出何种选择,char它都是与其他两种不同的类型,并且与任何一种都不兼容。
根据丹尼斯·里奇 (Dennis Ritchie) 的 C 编程语言一书,这是 ANSI C 的事实上的标准书,有符号或无符号的普通字符取决于机器,但可打印字符始终是正数。
根据 C 标准,普通字符的签名是“实现定义的”。
一般来说,实现者会选择在他们的架构上实现更有效的那个。在 x86 系统上,char 通常是有符号的。在 arm 系统上,它通常是未签名的(Apple iOS 是一个例外)。
现在,我们知道标准将其留给实施。
但是如何检查一个类型是signedor unsigned,比如char?
我写了一个宏来做到这一点:
#define IS_UNSIGNED(t) ((t)~1 > 0)
gcc并用、clang和测试它cl。但我不确定它对于其他情况总是安全的。