【发布时间】:2019-09-12 01:27:34
【问题描述】:
背景
几个 C++ 源材料和堆栈溢出问题讨论了 char 的实现依赖性质。也就是说,C++ 中的char 可以定义为unsigned char 或signed char,但根据ARM Linux FAQ,此实现depends entirely on the compiler:
上面的代码实际上是错误的,因为它假定类型“char”等价于“signed char”。 C 标准确实说“char”可以是“signed char”或“unsigned char”,这取决于编译器的实现或所遵循的平台。
这为歧义问题和不良做法打开了大门,包括mistaking the signage of a char 用作 8 位数字。 Rationale for C 提供了为什么会出现这种情况的一些原因,但没有解决留下歧义可能性的问题:
指定了三种类型的 char:signed、plain 和 unsigned。一个普通的 char 可以表示为有符号或无符号,这取决于实现,如在先前的实践中一样。引入有符号字符类型是为了在那些将普通字符实现为无符号的系统上提供单字节有符号整数类型。出于对称的原因,关键字signed 被允许作为其他整数类型的类型名称的一部分。
如果只保留unsigned char 和signed char 的类型作为8 位单元的两种数据类型,那么关闭甚至可能产生歧义的可能性似乎是有利的。这促使我提出这个问题......
问题
考虑到歧义的可能性,为什么要依赖 char 数据类型实现?
【问题讨论】:
-
char 类型在 C++ 中是一团糟。它们有 3 个完全不同的用途:字符串中的字符、字节和整数,在类型系统中无法消除它们之间的歧义。尝试
coutstd::int8_t...是的... -
一些处理器更喜欢有符号字符,而另一些处理器更喜欢无符号字符。例如,POWER 可以从内存中加载一个零扩展的 8 位值,但不是符号扩展。但是 SuperH-3 可以从内存中加载一个带有符号扩展但不能为零扩展的 8 位值。 C++ 派生自 C,C 保留了语言实现定义的许多细节,以便可以定制每个实现以使其最有效地适应其目标环境。
-
@RaymondChen 这应该是一个答案
-
@RaymondChen 根据 bolov 的建议,我已将您的评论作为社区 wiki 答案。
-
请记住,普通
char与signed char或unsigned char具有相同的表示形式,但它们仍然是三种不同且不兼容的类型。