char默认是签名还是未签名?

C L*_*ner 145 c signed types char

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

但我试图用GCC和Visual Studio验证这一点.它默认签名.

哪一个是正确的?

Alo*_*hal 188

这本书错了.该标准未指定plain char是签名还是未签名.

实际上,标准定义了三种不同的类型:char,signed char,和unsigned char.如果你#include <limits.h>然后看一下CHAR_MIN,你可以看出是否charsigned或是unsigned(如果CHAR_MIN小于0或等于0),但即便如此,就标准而言,这三种类型是不同的.

  • 这有一个歇斯底里,呃,历史的原因 - 在C的生命早期,"标准"被翻转至少两次,一些流行的早期编译器以一种方式结束而另一些则以另一种方式结束. (25认同)
  • @AlokSinghal:它也是在实现中定义`int`类型的位字段是有符号还是无符号. (9认同)
  • @eSKay:是的,`char`是唯一可以签名或未签名的类型.例如,`int`相当于`signed int`. (8认同)

R S*_*hko 65

正如Alok指出的那样,标准将其留给了实施.

对于gcc,默认值是signed,但您可以使用-funsigned-char.注意:对于Android NDK中的gcc,默认为unsigned.您还可以明确要求签名字符-fsigned-char.

在MSVC上,默认值已签名,但您可以使用/J.

  • [GCC docs](https://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/C-Dialect-Options.html)说它依赖于机器:"*每种机器都有默认值char应该是.默认情况下它类似于unsigned char,或者默认情况下是signed char.*" (10认同)
  • 有趣的是Schildt的描述与MSVC的行为不符,因为他的书通常面向MSVC用户.我想知道MS是否在某个时候改变了默认值? (2认同)
  • 我认为它不依赖于编译器,而是依赖于平台。我认为 char 被保留为第三种“字符数据类型”,以符合当时系统用作可打印字符的内容。 (2认同)
  • @Deduplicator那么,这个答案中的“_For gcc,默认是signed_”部分是错误的吗? (2认同)

Mic*_*urr 34

C99 N1256草案 6.2.5/15"类型"有关于签名类型的说法char:

实现应将char定义为具有与signed char或unsigned char相同的范围,表示和行为.

并在脚注中:

CHAR_MIN,定义在<limits.h>,将具有其中一个值0SCHAR_MIN,这可用于区分这两个选项.无论做出char何种选择,都是与其他两种类型不同的类型,并且与两者都不兼容.


小智 7

根据Dennis Ritchie的C编程语言书,这是ANSI C的事实上的标准书,无论是有符号还是无符号的普通字符都取决于机器,但可打印字符总是正面的.

  • 不一定是*printable*字符总是正面的情况.C标准保证基本执行字符集的所有成员都具有非负值. (8认同)

plu*_*ash 7

根据C标准,普通字符的签名是"实现定义".

一般来说,实现者选择在他们的架构上实现更高效的那个.在x86系统上,char通常是签名的.在arm系统上,它通常是未签名的(Apple iOS是一个例外).

  • @martinkunev Necropost 但是:我不认为有符号的 char 在 x86 上更有效,但它的效率也不比无符号低。选择它的原因还可能包括与默认为有符号的其他整数类型的一致性,并且由于有符号溢出是未定义的行为(即编译器可以假设它不会溢出),因此有符号类型有时可能会导致更好的优化。 (3认同)
  • @plugwash您的答案可能被否决了,因为[Tim Post丢了他的钥匙](https://meta.stackexchange.com/a/215397/349538)。严重的是,只要您确定答案正确(在这种情况下就是如此),就不必担心一次投票失败。我无数次无缘无故地删除我的帖子。不用担心,有时候人们只会做奇怪的事情。 (2认同)
  • 为什么signed char 在 x86 上效率更高?有什么来源吗? (2认同)