编译此程序时,-Wconversion
GCC参数会从标题中生成警告:
#include <iostream>
#include <array>
#include <string>
int main ()
{
std::string test = "1";
std::array<unsigned char, 1> byteArray;
byteArray[0] = byteArray[0] | test[0];
return 0;
}
以下是我编译它的方法:g++- -Wall -Wextra -Wconversion -pedantic -std=c++0x test.cpp
我正在使用GCC 4.5。
我在这里做违法的事吗?在某些情况下会引起问题吗?为什么|
会产生int
?
答案 0 :(得分:6)
我在这里做违法的事吗?
您正在从签名类型转换为无符号类型。如果有符号值为负,则无符号结果将是一个赋值定义的非负值(因此与初始值不同)。
在某些情况下会导致问题吗?
仅当值可能为负值时。在sizeof (char) == sizeof (int)
的某些异国情调的架构上可能会出现这种情况,或者如果您的代码执行的操作比使用|
组合两个值更复杂。
为什么
|
会产生int
?
因为在算术运算中使用之前,所有整数值都是提升。如果他们的类型小于int
,则会将其提升为int
。 (促销比这更多,但这是与这个问题相关的规则)。
答案 1 :(得分:2)
是的,一个字符串由char签名,你有一个unsigned char数组。
至|生成一个int,它叫做整数提升。基本上编译器使它们都是整数,一个|,然后再次使它们成为char。
虽然遇到了问题。根据C / C ++标准,如果提升的类型可以包含从中提升的所有类型的值,则会发生整数提升。所以它将unsigned char提升为unsigned int,将signed char提升为signed int。促销签名价值标志 - 扩展它。所以说你有-1或0xFF或11111111.那就是扩展到10000000000000000000000001111111 signed int((int)-1)。显然,与11111111((char)-1)相比,它会产生不同的结果。
请点击此处了解详情:here它解释了一种“解决方法”
答案 2 :(得分:2)
unsigned char | char
的结果为每integer conversion rules int
。当您将int
分配回unsigned char
时,赋值可以截断其int
值 - 编译器不知道您在此int
中的值有多大。
让编译器静音:
byteArray[0] = static_cast<unsigned char>(byteArray[0] | test[0]);