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访问对象的表示以正常工作.虽然没有明确的要求,但我认为这是标准中其他要求的要求.