从int转换为std :: array <unsigned char,=“”1ul =“”> :: value_type可能会改变其值</unsigned>

时间:2012-08-20 14:22:03

标签: c++ gcc char type-conversion bitwise-operators

编译此程序时,-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

3 个答案:

答案 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]);