Nie rozumiem, dlaczego otrzymuję to ostrzeżenie o konwersji między podpisanymi a niepodpisanymi, czy mój kompilator jest nieprawidłowy? [duplikować]

Nov 26 2020

Mam ten kod:

#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;
}

Z -Wsign-conversion kompiluje się bez ostrzeżenia na moim laptopie z systemem Linux, ale na osadzonym systemie Linux, na którym ma działać, pojawia się następujące ostrzeżenie:

temp.cpp: W funkcji „int main ()”: temp.cpp: 10:33: ostrzeżenie: konwersja do „std :: deque :: size_type {aka long unsigned int}” z „int” może zmienić znak wynik [-Wsign-conversion]

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

Po prostu nie rozumiem:

  • Mam włączoną konwersję -Wsign zarówno na moim laptopie z systemem Linux, jak i na wbudowanym systemie Linux, więc dlaczego pojawia się tylko ostrzeżenie o wbudowanym systemie Linux?
  • Jawnie rzutuję z intdo size_t(co nie powinno generować ostrzeżenia, ponieważ rzutowanie jest jawne), a następnie porównuję a size_tdo a std::deque<unsigned char>::size_type, więc gdzie jest niejawna konwersja z podpisanego na niepodpisany, która wyzwala ostrzeżenie ??!

Nie mogę pomóc, ale myślę, że kompilator na wbudowanym Linuksie jest tutaj zły. Czy coś mi brakuje?

Edycja: Na moim laptopie z Linuksem używam g ++ w wersji 9.3.0, podczas gdy na wbudowanym Linuksie używam g ++ w wersji 6.3.0 (prawdopodobnie nie jest to zwykły plik binarny, ponieważ jest to architektura ARM64)

Odpowiedzi

4 AdrianMole Nov 26 2020 at 18:22

Jest to niewątpliwie błąd / błąd we wbudowanym kompilatorze. Oddzielenie static_castod >=porównania usuwa ostrzeżenie, jak widać po przetestowaniu następującego kodu w Eksploratorze kompilatorów , z wybraną opcją ARM64 gcc 6.3.0 (linux):

#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;
}

Co więcej, ostrzeżenie znika również po przejściu na (32-bitowy) kompilator ARM gcc 6.3.0 (linux).