在“C 的完整参考”一书中提到,char
默认情况下它是无符号的。
但我试图用 GCC 和 Visual Studio 来验证这一点。默认情况下将其视为已签名。
哪一个是正确的?
书错了。该标准没有指定 plainchar
是有符号还是无符号。
事实上,该标准定义了三种不同的类型:char
、signed char
和unsigned char
。如果你#include <limits.h>
再看CHAR_MIN
,你可以发现 plainchar
是signed
or 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 是一个例外)。
现在,我们知道标准将其留给实施。
但是如何检查一个类型是signed
or unsigned
,比如char
?
我写了一个宏来做到这一点:
#define IS_UNSIGNED(t) ((t)~1 > 0)
gcc
并用、clang
和测试它cl
。但我不确定它对于其他情况总是安全的。