C ++:仅使用无符号类型时有符号/无符号不匹配

时间:2011-12-19 19:06:58

标签: c++ unsigned signed unsigned-integer

当我尝试使用启用了警告级别/ W4的Visual Studio 2010 C ++编译器(X86)编译以下C ++程序时,我在标记的行处收到签名/未签名的不匹配警告。

#include <cstdio>
#include <cstdint>
#include <cstddef>

int main(int argc, char **argv)
{
    size_t idx = 42;
    uint8_t bytesCount = 20;

    // warning C4389: '==' : signed/unsigned mismatch
    if (bytesCount + 1 == idx)
    {
        printf("Hello World\n");
    }

    // no warning
    if (bytesCount == idx)
    {
        printf("Hello World\n");
    }
}

这让我很困惑,因为我只使用无符号类型。自比较

bytesCount == idx

没有引起这样的警告,这可能与这里发生的一些奇怪的隐性对话有关。

因此:我得到这个警告的原因是什么,以及这种对话发生的规则(如果这是原因)?

4 个答案:

答案 0 :(得分:9)

1是签名文字。尝试使用bytesCount + 1U。

由于添加了有符号和无符号值(bytesCount + 1),编译器可能正在创建签名类型的临时值

答案 1 :(得分:5)

1int。整数算术表达式的类型取决于所涉及的类型。在这种情况下,您有unsigned类型和signed类型,其中unsigned类型小于signed类型。这属于表达式的C ++标准(第5.10节[expr]):

  

否则,如果带有符号整数类型的操作数的类型可以   表示带有unsigned的操作数类型的所有值   整数类型,带无符号整数类型的操作数应为   转换为带有符号整数类型的操作数类型。

即表达式bytesCount + 1的类型是int,默认情况下会签名。

答案 2 :(得分:3)

由于1属于int类型,因此表达式bytesCount + 1int(已签名)。

事实上,当在数学表达式中使用小于int的类型时,它会被提升为int,因此即使+ bytesCountbytesCount + bytesCount也会被视为int而不是uint8_t(而bytesCount + 1Uunsigned int,因为大于而不是int。)

following program输出true三次。

#include <iostream>

int main() 
{
    unsigned short s = 1;
    std::cout << (&typeid( s + 1U ) == &typeid(1U)) << std::endl;
    std::cout << (&typeid( + s ) == &typeid(1)) << std::endl;
    std::cout << (&typeid( s + s ) == &typeid(1)) << std::endl;
}

答案 3 :(得分:1)

其他答案已告诉您bytesCount + 1被解释为signed int。不过,我想在bytesCount == idx中添加bytesCount解释为signed int。从概念上讲,它首先转换为signed int,然后仅转换为unsigned int。您的编译器不会对此发出警告,因为它有足够的信息来确定没有真正的问题。转换为signed int不可能使bytesCount为负数。比较bytesCount + 1同样有效,同样安全,但只是稍微复杂一点,使编译器不再认为它是安全的。