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)
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With