Reputation: 545488
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?
Upvotes: 7
Views: 1478
Reputation: 55382
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.
Upvotes: 1
Reputation: 545488
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.
Upvotes: 2
Reputation: 171253
This has been fixed in GCC trunk, see PR 11856
So wait for approximately late April and use GCC 4.8 :-)
Upvotes: 11