8

编译此程序时,-WconversionGCC 参数会从标题中产生警告:

#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

4

3 回答 3

6

我在这里做违法的事吗?

您正在从有符号类型转换为无符号类型。如果有符号值为负,则无符号结果将是实现定义的非负值(因此与初始值不同)。

它会在某些情况下引起问题吗?

仅当值可能为负时。在有些奇特的架构上可能会出现这种情况sizeof (char) == sizeof (int),或者如果您的代码执行的操作比将两个值与|.

为什么会|产生一个int

因为所有整数值在用于算术运算之前都会被提升。如果它们的类型小于int,则将它们提升为int。(促销活动不止于此,但这是与此问题相关的规则)。

于 2012-08-20T14:29:54.153 回答
2

是的,一个字符串由带符号的字符组成,你有一个无符号字符数组。

至于作为| 产生一个int,它被称为整数提升。基本上,编译器将它们都设为int,执行|,然后再次将它们设为char。

但它遇到了问题。根据 C/C++ 标准,如果提升到的类型可以包含所提升的类型的所有值,则会发生整数提升。因此它将 unsigned char 提升为 unsigned int 并将signed char 提升为signed int。提升有符号值符号扩展它。所以假设你有 -1 或 0xFF 或 11111111。这扩展到 10000000000000000000000001111111 签名 int ((int)-1)。显然,这将产生与 |'ing 与 11111111 ((char)-1) 直观预期的结果不同的结果。

有关更多信息,请参见此处:此处解释了一种“解决方法”

于 2012-08-20T14:24:56.120 回答
2

结果 unsigned char | charint整数转换规则。当你int重新赋值时unsigned char,赋值会截断它的int值——编译器不知道你在这个中有多大的值int

要使编译器静音:

byteArray[0] = static_cast<unsigned char>(byteArray[0] | test[0]);

于 2012-08-20T14:30:32.263 回答