5

警告レベル/W4を有効にしてVisualStudio2010 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

4 に答える 4

9

1は符号付きリテラルです。bytesCount+1Uを試してください。

コンパイラは、符号付き値と符号なし値(bytesCount + 1)が追加されたため、符号付き型の一時値を作成している可能性があります。

于 2011-12-19T19:08:58.063 に答える
5

1ですint。整数算術式のタイプは、関係するタイプによって異なります。この場合、unsignedタイプとsignedタイプがunsignedタイプよりも小さいタイプがありsignedます。これは、式に関するC ++標準(セクション5.10 [expr])に該当します。

それ以外の場合、符号付き整数型のオペランドの型が符号なし整数型のオペランドの型のすべての値を表すことができる場合、符号なし整数型のオペランドは符号付き整数型のオペランドの型に変換されます。

つまり、式のタイプはbytesCount + 1デフォルトintで署名されています。

于 2011-12-19T19:19:25.097 に答える
3

1はタイプintであるため、式bytesCount + 1int(符号付き)です。

実際、よりも小さい型intが数式で使用される場合、それはに昇格されるintので、偶数+ bytesCountbytesCount + bytesCountあると見なされ、考慮intされませんuint8_t(ただしbytesCount + 1Uunsigned intそれはより大きいためですint)。

次のプログラムtrueは3回出力します。

#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;
}
于 2011-12-19T19:09:59.997 に答える
1

他の回答は、それbytesCount + 1がとして解釈されることをすでに示していますsigned int。ただし、これをに追加したいのですが、もとして解釈bytesCount == idxます。概念的には、最初にに変換され、その後にのみ変換されます。コンパイラは、実際には問題がないことを知るのに十分な情報を持っているため、これについて警告しません。への変換はおそらく否定的にすることはできません。比較は同じように有効で、同じように安全ですが、コンパイラが安全であると認識しなくなるために、少し複雑になります。bytesCountsigned intsigned intunsigned intsigned intbytesCountbytesCount + 1

于 2011-12-19T19:23:32.677 に答える