符号付きと符号なしの間の変換についてこの警告が表示される理由がわかりません。コンパイラが間違っていますか?[複製]

Nov 26 2020

私はこのコードを持っています:

#include <cstdint>
#include <deque>
#include <iostream>

int main()
{
    std::deque<uint8_t> receivedBytes;
    int nbExpectedBytes = 1;

    if (receivedBytes.size() >= static_cast<size_t>(nbExpectedBytes))
    {
        std::cout << "here" << std::endl;
    }
    return 0;
}

-Wsign-conversionを使用すると、これはLinuxラップトップでは警告なしにコンパイルされますが、実行する予定の組み込みLinuxでは次の警告が表示されます。

temp.cpp:関数内 'int main()':temp.cpp:10:3​​3:警告: 'int'から 'std :: deque :: size_type {aka long unsigned int}'への変換により、結果[-Wsign-conversion]

 if (receivedBytes.size() >= static_cast<size_t>(nbExpectedBytes))
                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

私は理解していません:

  • Linuxラップトップと組み込みLinuxの両方で-Wsign-conversionを有効にしているのに、組み込みLinuxでのみ警告が表示されるのはなぜですか?
  • からintを明示的にキャストしsize_t(キャストが明示的であるため警告を生成しないはずです)、次にasize_tをaと比較しているstd::deque<unsigned char>::size_typeので、警告をトリガーする符号付きから符号なしへの暗黙の変換はどこにありますか??!

組み込みLinuxのコンパイラがここで間違っていると思わずにはいられません。私は何かが足りないのですか?

編集:私のLinuxラップトップではg ++バージョン9.3.0を使用していますが、組み込みLinuxではg ++バージョン6.3.0を使用しています(ARM64アーキテクチャであるためおそらく通常のバイナリではありません)

回答

4 AdrianMole Nov 26 2020 at 18:22

これは間違いなく組み込みコンパイラのバグ/エラーです。を比較static_castから分離すると、ARM64 gcc 6.3.0(linux)を選択>=してCompiler Explorerで次のコードをテストすることからわかるように、警告が削除されます。

#include <deque>
#include <cstddef>
#include <cstdint>

int main()
{
    std::deque<uint8_t> receivedBytes;
    int nbExpectedBytes = 1;

    // Warning generated ...
    while (receivedBytes.size() >= static_cast<size_t>(nbExpectedBytes))
    {
        break;
    }

    // Warning NOT generated ...
    size_t blob = static_cast<size_t>(nbExpectedBytes);
    while (receivedBytes.size() >= blob)
    {
        break;
    }
    return 0;
}

さらに、(32ビット)ARM gcc 6.3.0(linux)コンパイラに変更すると、警告も消えます。