Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting warnings for implicit conversion overflow from unsigned to signed

Consider the following problematic code:

#include <iostream>

void foo(int64_t y) {
    std::cout << y << "\n";
}

int main() {
    uint64_t x = 14400000000000000000ull;
    foo(x);
}

Typically prints -4046744073709551616.

How can one get the compiler to help with this type of conversion/overflow issue? I have tried the following:

g++ -g overflow.cpp -fsanitize=undefined -Wall -Wextra -pedantic -Wconversion -Wconversion
clang++ -g overflow.cpp -fsanitize=undefined,integer,implicit-conversion -Wall -Wextra -pedantic

None of which gives any compile- or run-time warning.

(clang version 7.0.0, gcc version 8.2.1)

like image 604
Zulan Avatar asked Aug 27 '26 00:08

Zulan


2 Answers

The issue here is that -Wconversion is only going to warn if the value, when cast back to the source type, may not be the same type. For example if foo were to take an int instead then -Wconversion will issue a warning because it is possible that you can't cast the value in the int back to the original uint64_t value. If we have

uint64_t u = some_value;
int64_t s = static_cast<int64_t>(u);
uint64_t check = static_cast<uint64_t>(s)

then check == u will always be true (so long as int64_t is also two's compliment) so -Wconversion will not issue a warning because we get the source value back.

What you'll need in this case is

-Wsign-conversion

which will warning you that the signs mismatch.

like image 199
NathanOliver Avatar answered Aug 29 '26 15:08

NathanOliver


GCC and Clang both have the warning option -Wsign-conversion to issue a warning in cases like this.

warning: implicit conversion changes signedness: 'uint64_t' (aka 'unsigned long') to 'int64_t' (aka 'long') [-Wsign-conversion]

Note GCC's documentation about -Wconversion

... Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.

Also note that the program is well-formed (thus must compile succesfully) and has no undefined behaviour (and thus no reason to trigger the sanitizer). Converting unrepresentable number to signed results in implementation defined value.

like image 32
eerorika Avatar answered Aug 29 '26 13:08

eerorika



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!