GCC (4.7.2) with -Wextra
signals the following warning/error (I have -Werror
enabled):
Comparison is always true due to limited range of data type [-Wtype-limits]
for the following code [try online]:
template <
typename T,
std::size_t N,
bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N>
struct validator {
static constexpr bool validate(T value) {
return static_cast<std::size_t>(value) < N;
}
};
template <typename T, std::size_t N>
struct validator<T, N, true> {
static constexpr bool validate(T) {
return true;
}
};
int main() {
// Works
static_assert(validator<int, 4>::validate(3), "Invalid");
// Error :-(
static_assert(validator<bool, 2>::validate(true), "Invalid");
}
I understand why the warning would occur in a normal expression context, e.g. when I would have used the following validate
function:
template <typename T, std::size_t N>
bool validate(T value) {
return static_cast<std::size_t>(value) < N;
}
– In fact, that’s why I am using the specialised template in the first place (and note that the correct template specialisation is used, and the error in my first code is raised by the template argument, not inside the function in the unspecialised template). Is there a way around this warning? If not, isn’t that a bug in the compiler?
This has been fixed in GCC trunk, see PR 11856
So wait for approximately late April and use GCC 4.8 :-)
Since I can’t wait until this is fixed (see Jonathan’s answer) I’ve selectively disabled the warning using GCC #pragma
extensions:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
static_assert(validator<bool, 2>::validate(true), "Invalid");
#pragma GCC diagnostic pop
Note that these pragmas unfortunately need to surround the calling code even though the actual error happens in the template parameter.
Here's a workaround:
template <
typename T,
std::size_t N,
bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N>
struct validator {
static constexpr bool validate(T value) {
return size_t_cast(value) < N;
}
private:
static constexpr std::size_t size_t_cast(T value) {
return value;
}
};
template <typename T, std::size_t N>
struct validator<T, N, true> {
static constexpr bool validate(T) {
return true;
}
};
This allows the example to compile without errors in GCC 4.7.2.
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