为什么作为符号或无符号不是C或C ++标准明确定义字符?(Why don't the C o

2019-07-22 04:52发布

int main()
{
    char c = 0xff;
    bool b = 0xff == c;
    // Under most C/C++ compilers' default options, b is FALSE!!!
}

无论是C或C ++标准指定焦炭用作符号或无符号,它是实现定义。

为什么作为符号或无符号,以避免像上面的代码危险误用C / C ++标准没有明确定义字符?

Answer 1:

由于历史原因,大部分。

类型的表达式char都提升到int在大多数情况下(因为很多CPU不具有8位算术运算)。 在某些系统中,符号扩展是为了做到这一点的最有效方法,它主张使普通char签署。

在另一方面,在EBCDIC字符集具有与所述高位比特组基本的字符(即,具有128或更大的值的字符); 在EBCDIC平台上, char几乎必须是无符号。

在ANSI C的理由 (在1989年标准)没有很多话要说; 部分3.1.2.5说:

三种类型的字符指定: signed ,平原,和unsigned 。 一个普通char作为符号或无符号的,根据实施方式,如在现有实践中可以被表示。 该类型signed char被介绍给做出那些实施的char为无符号的系统可用一个字节有符号整数类型。 对于对称的原因,关键字signed允许其他整数类型的类型名称的一部分。

让我们回到更进一步,在一个早期版本的C参考手册从1975年说:

char对象可以在任何地方使用的int的可能。 在所有情况下, char被转换为int通过所得整数的高位8比特传播其符号。 这是用于字符和整数的二进制补码表示是一致的。 (然而,该符号传播特性在其他实现中消失。)

这个描述更实现特定的比我们在以后的文件看,但它确实承认, char可以或者带符号。 在其上“的标志传播消失”该“其它实施方式”,促进一个的char对象int将具有零扩展的8位表示的,基本上把它当作一个8位的无符号的数量。 (语言还不具备signedunsigned关键字)。

C'S直接前身是一种叫做硼。硼语言是无类型语言,所以问题char被签名或签名并不适用。 有关C的早期历史的更多信息,请参见后期丹尼斯里奇的主页 ,现在搬到这里 。

至于发生的事情在你的代码(应用现代C规则):

char c = 0xff;
bool b = 0xff == c;

如果纯char是无符号的,则初始化c其设置为(char)0xff ,与之相比,等于0xff在第二行。 但是,如果滑动char进行签名,然后0xff (类型的表达式int )转化为char -但由于0xff超过CHAR_MAX(假设CHAR_BIT==8 ),其结果是实现定义 。 在大多数实现,结果是-1 。 在比较0xff == c ,两个操作数被转换为int ,使得它等同于0xff == -1 ,或255 == -1 ,这是当然假。

另一个需要注意的重要一点是unsigned charsigned char ,和(平) char三种不同类型。 char具有相同的表示为任一 unsigned char signed char ; 它的实现定义它是哪一个。 (在另一方面, signed intint是同一类型的两个名字; unsigned int是不同的类型(除了,只是添加到轻薄,它的实现定义声明为纯位字段是否。 int签署或无符号的。))

是的,这一切都有点乱,我敢肯定,这将如果C正在从头开始设计今天已经被不同的定义。 但C语言的每次改版不得不避免破坏(太多)现有的代码,并在较小程度上现有实现的。



Answer 2:

char最初是为了存储字符,因此,无论是带符号并不重要。 真正重要的是如何在执行数学char有效。 因此,依赖于系统,编译器会选择什么是最合适的

ARMv4之前,ARM已经加载半字和符号字节没有原生支持。 要加载符号字节,你必须LDRB然后签署延长值(LSL起来然后ASR它背下来)。 这是痛苦所以焦炭在默认情况下无符号的。

为什么无符号的类型是ARM CPU比较有效?

其实有很多的ARM编译器仍然采用unsigned char在默认情况下,因为即使你可以加载与现代ARM ISA的符号扩展一个字节,该指令仍低于零扩展版本不够灵活

  • 是char签署或默认iOS上的无符号?
  • charunsigned默认情况下,在Android NDK

而最现代的编译器还允许您更改字符的signness而不是使用默认设置



文章来源: Why don't the C or C++ standards explicitly define char as signed or unsigned?