서명 된 것과 서명되지 않은 것 간의 변환에 대해이 경고가 표시되는 이유를 이해할 수 없습니다. 컴파일러가 잘못 되었습니까? [복제]

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 : 33 : 경고 : 'int'에서 'std :: deque :: size_type {aka long unsigned int}'로 변환하면 결과 [-Wsign-conversion]

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

이해가 안 돼요 :

  • 내 리눅스 노트북과 임베디드 리눅스 모두에서 -Wsign-conversion이 활성화되어 있는데 왜 임베디드 리눅스에서만 경고를 받나요?
  • 나는 명시 적으로에서 int로 캐스팅 하고 size_t(캐스트가 명시 적이므로 경고를 생성해서는 안 됨) size_ta std::deque<unsigned char>::size_type와 비교 하므로 경고를 트리거하는 서명에서 서명되지 않음으로의 암시 적 변환은 어디에 있습니까 ??!

나는 도울 수 없지만 임베디드 리눅스의 컴파일러가 여기에서 잘못되었다고 생각합니다. 내가 뭔가를 놓치고 있습니까?

편집 : 내 리눅스 노트북에서는 g ++ 버전 9.3.0을 사용하고 있고 임베디드 리눅스에서는 g ++ 버전 6.3.0을 사용하고 있습니다 (아마도 ARM64 아키텍처이기 때문에 일반적인 바이너리가 아닐 것입니다)

답변

4 AdrianMole Nov 26 2020 at 18:22

이것은 의심 할 여지없이 임베디드 컴파일러의 버그 / 오류입니다. 비교 static_cast에서를 분리하면 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;
}

또한 (32 비트) ARM gcc 6.3.0 (linux) 컴파일러로 변경하면 경고도 사라집니다.