为什么C/C++讨厌签名这么多?

为什么C允许使用“字符类型”访问对象:

6.5 Expressions (C)

An object shall have its stored value accessed only by an lvalue expression that has one ofthe following types:

  • a character type.

但是C只允许char和unsigned char?

3.10 Lvalues and rvalues (C++)

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • a char or unsigned char type.

另一部分已经签字的仇恨(C标准引用):

3.9 Types (C++)

For any object (other than a base-class subobject) of trivially copyable type T,whether or not the object holds a valid value of type T,the underlying bytes making up the object can be copied into an array of char or unsigned char. If the content of the array of char or unsigned char is copied back into the object,the object shall subsequently hold its original value.

并从C标准:

6.2.6 Representations of types (C)

Values stored in non-bit-field objects of any other object type consist of n × CHAR_BIT bits,where n is the size of an object of that type,in bytes. The value may be copied into an object of type unsigned char [n] (e.g.,by memcpy); the resulting set of bytes is called the object representation of the value.

我可以看到很多人在stackoverflow说这是因为unsigned char是唯一的字符类型,保证没有填充位,但C99第6.2.6.2节整数类型说

signed char shall not have any padding bits

那么背后的真正原因是什么呢?

解决方法

这是我的动机:

在非二进制补码系统上,signed char不适合访问对象的表示.这是因为有两个可能的有符号的char表示具有相同的值(0和-0),或者一个没有值的表示(陷阱表示).在这两种情况下,这样可以防止您对对象的表示做最有意义的事情.例如,如果你有一个16位的无符号整数0x80ff,一个或另一个字节作为一个有符号的字符,将要陷阱或比较等于0.

请注意,在这种实现(非二进制补码)中,plain char需要定义为无符号类型,用于通过char访问对象的表示以正常工作.虽然没有明确的要求,但我认为这是标准中其他要求的要求.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...