Reputation: 1594
I have a function that performs a negative check on a value of a generic type (well I don't want to assume the type, it is not necessarily templated). However, with -Wtype-limits
enabled, the compiler complains about the negative check if the type in question is an unsigned type. Removing the negative check is a bad idea if the type might change to be a signed type, and disabling the warnings is not ideal, as it might catch legitimate issues.
using example_t = uint8_t; // could be int8_t or int64_t or really whatever integer type that can store values 0 - 8.
void example(example_t value) {
if (value < 0 || value >= 9) { // <-- errors on the 'value < 0' check
throw std::invalid_argument("some error message");
}
// continue processing ...
}
Even if I use C++17 and use if constexpr(std::is_unsigned<example_t>::value)
to guard the check that is warning, it still warns. I've noticed that GCC does not emit warning for if constexpr
'd out code if it would trigger warnings because the value assigned into variables of those type would fall out of the range of the type. Also, GCC emits the warning even if I cast it to a signed int
first. The warning behavior is not consistent with itself, so this seems like a bug. Clang issues no warning at all for these types of checks.
But I wondering if there was a way around this, my code base is strictly C++14 compliant, and we are stuck with old GCC compilers.
Upvotes: 2
Views: 389
Reputation: 22152
I am not sure it is worth the impact on readability, but you can move the comparison into a template context using a generic lambda. GCC doesn't warn about this in the templated code:
if ([](auto v){return v < 0;}(value) || value >= 9)
or maybe better write a function:
template<typename T>
constexpr bool is_negative(T t) { return t < 0; }
and use that:
if (is_negative(value) || value >= 9)
or just using std::less
also wont warn:
if (std::less()(value, 0) || value >= 9)
GCC also has #pragma
s to disable warnings temporarily, see this question:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
if (value < 0 || value >= 9) {
throw std::invalid_argument("some error message");
}
#pragma GCC diagnostic pop
Upvotes: 2