在C++;11标准,为什么让char类型实现依赖于它? 背景 几个C++源代码和堆栈溢出问题讨论了代码< char < /> >的实现依赖性。也就是说,C++中的代码> char < /C> >可以定义为未签名的char < /> >或符号char < /> >,但根据ARMLINUX FAQ:实现

在C++;11标准,为什么让char类型实现依赖于它? 背景 几个C++源代码和堆栈溢出问题讨论了代码< char < /> >的实现依赖性。也就是说,C++中的代码> char < /C> >可以定义为未签名的char < /> >或符号char < /> >,但根据ARMLINUX FAQ:实现,c++,char,C++,Char,上面的代码实际上是错误的,因为它假定类型“char”等同于“signed char”。C标准确实规定“char”可以是“有符号的char”或“无符号的char”,这取决于编译器实现或遵循的平台 这为歧义问题和不良做法(包括用作8位数字时)敞开了大门。报告提供了一些理由来解释为什么会出现这种情况,但并没有解决保留模棱两可可能性的问题: 指定了三种类型的字符:有符号、普通和无符号。普通字符可以表示为有符号或无符号,这取决于实现,与以前的实践相同。引入类型signed char是为了在那些将纯字符实现

上面的代码实际上是错误的,因为它假定类型“char”等同于“signed char”。C标准确实规定“char”可以是“有符号的char”或“无符号的char”,这取决于编译器实现或遵循的平台

这为歧义问题和不良做法(包括用作8位数字时)敞开了大门。报告提供了一些理由来解释为什么会出现这种情况,但并没有解决保留模棱两可可能性的问题:

指定了三种类型的字符:有符号、普通和无符号。普通字符可以表示为有符号或无符号,这取决于实现,与以前的实践相同。引入类型signed char是为了在那些将纯字符实现为无符号的系统上提供一个单字节有符号整数类型。出于对称性的原因,允许将关键字signed作为其他整数类型的类型名的一部分

无符号字符
有符号字符
的类型作为8位单元的两种数据类型似乎有利于消除歧义。这促使我提出一个问题

问题:
考虑到可能存在歧义,为什么让
char
数据类型实现依赖于它呢?

一些处理器更喜欢有符号的char,而其他处理器更喜欢无符号的char。例如,POWER可以从具有零扩展名的内存加载8位值,但不能加载符号扩展名。但是SuperH-3可以从具有符号扩展但不具有零扩展的内存中加载8位值。C++源自C++,C留下了许多定义的语言实现细节,以便每个实现都可以被定制为其目标环境最有效的。它们有3个完全不同的用途:字符串中的字符、字节和整数,在类型系统中无法消除它们之间的歧义。尝试
cout
a
std::int8\u t
。。。是的…一些处理器更喜欢有符号字符,而其他处理器更喜欢无符号字符。例如,POWER可以从具有零扩展名的内存加载8位值,但不能加载符号扩展名。但是SuperH-3可以从具有符号扩展但不具有零扩展的内存中加载8位值。C++源自C语言,C语言保留了语言实现的许多细节,这样每个实现都可以根据其目标环境进行调整,以达到最高效的效果。@RaymondChen这应该是一个answer@RaymondChen根据博洛夫的建议,我已将您的评论作为社区维基的答案。请记住,普通的
char
也有相同的答案表示为
signed char
unsigned char
,但它们是三种不同且不兼容的类型。重要的是,当使用
char
作为实际字符数据时,符号并不重要(您的古怪ASCII超集的标志符号可以用负值引用,就像用正值引用一样容易)因此,在这种情况下,使用任何一种更有效的类型都可以。只有在数学中使用它时,实现定义的有符号性才是一个问题。在这种情况下,您应该明确指定有符号性,或者只使用类似于
uint8_t
/
int8_t
的stdint类型来明确您依赖于数字行为,而不仅仅是存储字符。