为什么char与签名char或未签名char不兼容? [英] Why is char not compatible with signed char or unsigned char?

查看:120
本文介绍了为什么char与签名char或未签名char不兼容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现C99标准中有一条语句拒绝char类型与带符号的char /未签名的类型之间的兼容性。

I have found that the C99 standard have a statement which denies the compatibility between the type char and the type signed char/unsigned char.

C99标准的注释35 :

Note 35 of C99 standard:


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

CHAR_MIN, defined in limits.h, will have one of the values 0 or SCHAR_MIN, and this can be used to distinguish the two options. Irrespective of the choice made, char is a separate type from the other two and is not compatible with either.

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

My question is that why does the committee deny the compatibility? What is the rationale? If char is compatible with signed char or unsigned char, will something terrible happen?

推荐答案

其根在编译器历史记录中。八十年代基本上有两个C语言方言:

The roots are in compiler history. There were (are) essentially two C dialects in the Eighties:


  1. 签署普通字符的地方

  2. 在普通字符未签名的地方

C89应该对其中哪些进行标准化? C89选择不对它们进行标准化,因为它会使已经编写的C代码中的许多假设无效(标准人士称之为已安装的基础)。因此C89做了K& R所做的:保留纯字符实现的签名定义。如果您需要特定的签名,请限定您的字符。
现代编译器通常允许您选择带有选项的方言(例如gcc的 -funsigned-char )。

Which of these should C89 have standardized? C89 chose to standardize neither, because it would have invalidated a large number of assumptions made in C code already written--what standard folks call the installed base. So C89 did what K&R did: leave the signedness of plain char implementation-defined. If you required a specific signedness, qualify your char. Modern compilers usually let you chose the dialect with an option (eg. gcc's -funsigned-char).

如果忽略(未)有符号字符和纯字符之间的区别,可能会发生可怕的事情是,如果您在不考虑这些细节的情况下进行算术和移位,那么当您不使用这些字符时,可能会得到符号扩展名

The "terrible" thing that can happen if you ignore the distinction between (un)signed char and plain char is that if you do arithmetic and shifts without taking these details into account, you might get sign extensions when you don't expect them or vice versa (or even undefined behavior when shifting).

还有一些愚蠢的建议,建议始终使用显式带符号或无符号限定符声明字符。只要您仅使用指向此类合格类型的指针,此方法便会起作用,但是一旦您处理字符串和字符串函数,所有这些操作都在指向纯字符的指针上进行,则它需要进行难看的强制类型转换,如果不进行强制转换,则不兼容分配。这样的代码突然被大量的丑陋骨头所覆盖。

There's also some dumb advice out there that recommends to always declare your chars with an explicit signed or unsigned qualifier. This works as long as you only work with pointers to such qualified types, but it requires ugly casts as soon as you deal with strings and string functions, all of which operate on pointer-to-plain-char, which is assignment-incompatible without a cast. Such code suddenly gets plastered with tons of ugly-to-the-bone casts.

字符的基本规则是:


  • 对字符串使用普通 char ,如果需要将指针传递给采用普通字符的函数

  • 如果需要位旋转和字节移位,请使用无符号字符

  • 使用 signed char 如果需要小的带符号的值,但是如果空间不是问题,请考虑使用 int

  • Use plain char for strings and if you need to pass pointers to functions taking plain char
  • Use unsigned char if you need to do bit twiddling and shifting on bytes
  • Use signed char if you need small signed values, but think about using int if space is not a concern

这篇关于为什么char与签名char或未签名char不兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆