Je ne comprends pas pourquoi je reçois cet avertissement concernant la conversion entre signé et non signé, mon compilateur est-il faux? [dupliquer]

Nov 26 2020

J'ai ce code:

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

Avec -Wsign-conversion, cela compile sans avertissement sur mon ordinateur portable Linux, mais sur le Linux intégré sur lequel il est censé fonctionner, j'obtiens l'avertissement suivant:

temp.cpp: Dans la fonction 'int main ()': temp.cpp: 10: 33: avertissement: la conversion en 'std :: deque :: size_type {aka long unsigned int}' de 'int' peut changer le signe du résultat [-Wsign-conversion]

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

Je ne comprends tout simplement pas:

  • J'ai -Wsign-conversion activé à la fois sur mon ordinateur portable Linux et sur le Linux intégré, alors pourquoi est-ce que je reçois uniquement l'avertissement sur le Linux intégré?
  • Je lance explicitement de intvers size_t(ce qui ne devrait pas produire d'avertissement car le cast est explicite), puis je compare a size_tà a std::deque<unsigned char>::size_type, alors où est la conversion implicite de signé à non signé qui déclenche l'avertissement ??!

Je ne peux pas m'empêcher de penser que le compilateur sur le Linux embarqué est faux ici. Est-ce que je manque quelque chose?

Edit: Sur mon ordinateur portable Linux, j'utilise g ++ version 9.3.0, tandis que sur le Linux embarqué, j'utilise g ++ version 6.3.0 (probablement pas le binaire habituel puisqu'il s'agit d'une architecture ARM64)

Réponses

4 AdrianMole Nov 26 2020 at 18:22

Il s'agit sans aucun doute d' un bogue / erreur dans le compilateur intégré. Séparer le static_castde la >=comparaison supprime l'avertissement, comme on peut le voir en testant le code suivant sur l' Explorateur de compilateurs , avec ARM64 gcc 6.3.0 (linux) sélectionné:

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

De plus, l'avertissement disparaît également lors du passage au compilateur ARM gcc 6.3.0 (linux) (32 bits).