是否真的有必要unsigned char
像在一些处理字符编码或二进制缓冲区的库中一样使用二进制数据?要理解我的问题,请看下面的代码 -
char c[5], d[5];
c[0] = 0xF0;
c[1] = 0xA4;
c[2] = 0xAD;
c[3] = 0xA2;
c[4] = '\0';
printf("%s\n", c);
memcpy(d, c, 5);
printf("%s\n", d);
Run Code Online (Sandbox Code Playgroud)
两者printf's
输出 correctly, where
f0 a4 ad a2
Unicode代码点的编码U+24B62 ()
在十六进制中.
甚至memcpy
还正确地复制了char所持有的位.
什么推理可能主张使用unsigned char
而不是plain char
?
在其他相关问题unsigned char
中突出显示,因为它是唯一的(字节/最小)数据类型,保证C规范没有填充.但正如上面的例子所示,输出似乎不受任何填充的影响.
我使用VC++ Express 2010和MinGW来编译上面的内容.虽然VC给出了警告
warning C4309: '=' : truncation of constant value
输出似乎没有反映出来.
PS这可以标记为可能重复的字节缓冲区应该是有符号的还是无符号的char缓冲区?但我的意图是不同的.我在问为什么一些似乎工作正常的东西char
应该输入unsigned char
?
更新:引用N3337,
Section …
为什么C允许使用"字符类型"访问对象:
6.5表达式(C)
对象的存储值只能由具有以下类型之一的左值表达式访问:
- 一个字符类型.
但C++只允许char和unsigned char?
3.10左值和右值(C++)
如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
- char或unsigned char类型.
另一部分签名的仇恨(引自C++标准):
3.9类型(C++)
对于普通可复制类型T的任何对象(基类子对象除外),无论对象是否保持类型T的有效值,组成对象的基础字节都可以复制到char或unsigned char数组中.如果将char或unsigned char数组的内容复制回对象,则该对象应随后保持其原始值.
并从C标准:
6.2.6类型表示(C)
存储在任何其他对象类型的非位字段对象中的值由n×CHAR_BIT位组成,其中n是该类型对象的大小(以字节为单位).可以将该值复制到unsigned char [n] 类型的对象中(例如,通过memcpy); 生成的字节集称为值的对象表示.
我可以在stackoverflow上看到很多人说这是因为unsigned char是唯一保证没有填充位的字符类型,但是C99第6.2.6.2节整数类型说
signed char不应有任何填充位
那么这背后的真正原因是什么?
当存储"字节数组"(blobs ...)时,使用char
或更好地使用unsigned char
项目(unsigned char
又名uint8_t
)?(标准说sizeof
两者都是1字节.)
它有关系吗?或者一个比另一个更方便或更普遍?也许,像Boost这样的图书馆会用到什么?