Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I don't understand why I get this warning about conversion between signed and unsigned, is my compiler wrong? [duplicate]

I have this 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;
}

With -Wsign-conversion, this compiles without warning on my linux laptop, but on the embedded linux on which it's meant to run I get the following warning :

temp.cpp: In function ‘int main()’: temp.cpp:10:33: warning: conversion to ‘std::deque::size_type {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]

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

I just don't understand:

  • I have -Wsign-conversion enabled both on my linux laptop and on the embedded linux, so why do I only get the warning on the embedded linux?
  • I'm explicitly casting from int to size_t (which should not produce a warning because the cast is explicit), then comparing a size_t to a std::deque<unsigned char>::size_type, so where is the implicit conversion from signed to unsigned that triggers the warning??!

I can't help but think the compiler on the embedded linux is wrong here. Am I missing something?

Edit: On my linux laptop I'm using g++ version 9.3.0, while on the embedded linux I'm using g++ version 6.3.0 (probably not the usual binary since it's an ARM64 architecture)

like image 760
Eternal Avatar asked Nov 26 '20 10:11

Eternal


1 Answers

This is undoubtedly a bug/error in the embedded compiler. Separating the static_cast from the >= comparison removes the warning, as can be seen from testing the following code on Compiler Explorer, with ARM64 gcc 6.3.0 (linux) selected:

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

Further, the warning also disappears when changing to the (32-bit) ARM gcc 6.3.0 (linux) compiler.

like image 161
Adrian Mole Avatar answered Oct 16 '22 21:10

Adrian Mole