为什么char与signed char或unsigned char不兼容?

时间:2012-10-07 14:06:00

标签: c char compatibility

我发现C99标准有一个声明,它拒绝了char类型和signed char / unsigned char类型之间的兼容性。

C99标准的注释35:

  

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

我的问题是为什么委员会否认兼容性?理由是什么?如果char与signed char或unsigned char兼容,会发生什么可怕的事情吗?

2 个答案:

答案 0 :(得分:11)

根位于编译器历史记录中。八十年代基本上有两种C方言:

  1. 签署普通字符
  2. 其中普通字符未签名
  3. C89中哪一个应该标准化? C89选择不标准化,因为它会使已编写的C代码中的大量假设无效 - 标准人员称之为已安装的基础。所以C89做了K& R所做的事情:保留了普通字符实现定义的签名。如果您需要特定的签名,请对您的字符进行限定。 现代编译器通常会让你选择带有选项的方言(例如gcc的-funsigned-char)。

    如果忽略(un)signed char和plain char之间的区别,可能发生的“可怕”事情是,如果你在不考虑这些细节的情况下进行算术和移位,那么当你不这样做时,你可能会得到符号扩展期望它们,反之亦然(甚至在转移时也不确定行为)。

    还有一些愚蠢的建议,建议总是使用显式签名或无符号限定符声明你的字符。只要您只使用指向这些限定类型的指针,这就可以工作,但只要您处理字符串和字符串函数,它就会需要丑陋的转换,所有这些都在指向普通字符的指针上运行,没有强制转换,它是赋值不兼容的。这样的代码突然变成了大量丑陋的角色。

    字符的基本规则是:

    • 对字符串使用plain char,如果需要将指针传递给使用plain char
    • 的函数
    • 使用unsigned char如果你需要做一点翻转和转换字节
    • 如果您需要较小的签名值,请使用signed char,但如果空间不是问题,请考虑使用int

答案 1 :(得分:2)

signed charunsigned char视为最小的算术,整数类型,就像signed short / unsigned short一样,等等int,{{ 1}},long int。这些类型都是明确的。

另一方面,long long int的用途非常不同:它是I / O的基本类型和与系统的通信。它不是用于计算,而是用作数据的单位。这就是为什么你在命令行参数,“字符串”的定义,char函数和其他读/写类型IO函数中以及在例外中找到char的原因。严格的别名规则。故意不严格定义此FILE*类型,以便允许每个实现使用最“自然”的表示。

这只是分离责任的问题。

(诚然,char 布局兼容同时包含charsigned char,因此您可以明确地将其中一个转换为另一个然后回来。)