为什么C或C ++标准没有明确地将char定义为signed或unsigned?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么C或C ++标准没有明确地将char定义为signed或unsigned?相关的知识,希望对你有一定的参考价值。
int main()
{
char c = 0xff;
bool b = 0xff == c;
// Under most C/C++ compilers' default options, b is FALSE!!!
}
C或C ++标准都没有将char指定为有符号或无符号,它是实现定义的。
为什么C / C ++标准没有明确地将char定义为有符号或无符号以避免像上述代码那样的危险误用?
历史原因,大多数。
在大多数情况下,char
类型的表达式被提升为int
(因为许多CPU没有8位算术运算)。在某些系统上,符号扩展是最有效的方法,这使得简单的char
签名。
另一方面,EBCDIC字符集具有高位设置的基本字符(即,值为128或更大的字符);在EBCDIC平台上,char
几乎必须是未签名的。
ANSI C Rationale(1989年标准)在这个问题上没有太多可说的;第3.1.2.5节说:
指定了三种类型的char:
signed
,plain和unsigned
。根据实施情况,普通的char
可以表示为有符号或无符号,如在先前的实践中那样。引入类型signed char
是为了在那些实现普通char为unsigned的系统上提供一个单字节有符号整数类型。出于对称的原因,允许使用关键字signed
作为其他整数类型的类型名称的一部分。
更进一步,1975年的C Reference Manual的早期版本说:
在
char
可能的任何地方都可以使用int
物体。在所有情况下,char
通过将其符号传播到结果整数的高8位来转换为int
。这与用于字符和整数的二进制补码表示一致。 (但是,符号传播功能在其他实现中会消失。)
此描述比我们在后面的文档中看到的更具实现性,但它确实承认char
可能是签名的或未签名的。在“符号传播消失”的“其他实现”上,将char
对象提升为int
将对8位表示进行零扩展,基本上将其视为8位无符号数量。 (该语言还没有signed
或unsigned
关键字。)
C的直接前身是一种叫做B的语言.B是一种无类型语言,所以char
被签名或未签名的问题不适用。有关C的早期历史的更多信息,请参阅已故的Dennis Ritchie's
home page
,现在moved here。
至于你的代码中发生了什么(应用现代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 char
,signed char
和(plain)char
是三种不同的类型。 char
与unsigned char
或signed char
具有相同的代表性;它的实现定义了它是哪一个。 (另一方面,signed int
和int
是同一类型的两个名字; unsigned int
是一个独特的类型。(除此之外,只是为了添加到轻浮,它的实现 - 定义声明为int
的位字段是有符号还是无符号。))
是的,这一切都有点混乱,而且我敢肯定,如果今天从头开始设计C,它的定义会有所不同。但是,C语言的每个版本都必须避免破坏(过多)现有代码,并在较小程度上避免现有实现。
char
最初用于存储字符,因此无论是签名还是未签名都不重要。真正重要的是如何有效地在char
上执行数学运算。所以依赖于系统,编译器会选择最合适的
在ARMv4之前,ARM没有本机支持加载半字和有符号字节。要加载一个有符号的字节,你必须LDRB然后签名扩展该值(LSL它然后ASR它退回)。这很痛苦,因此默认情况下char未签名。
事实上,许多ARM编译器默认仍然使用unsigned char
,因为即使您可以在现代ARM ISA上加载带符号扩展的字节,该指令仍然不如零扩展版本灵活
大多数现代编译器还允许您更改char的符号,而不是使用默认设置
以上是关于为什么C或C ++标准没有明确地将char定义为signed或unsigned?的主要内容,如果未能解决你的问题,请参考以下文章