"Предупреждение: сравнение всегда верно"

GCC (4.7.2) с -Wextra сигнализирует следующее предупреждение/ошибку (у меня есть -Werror включено):

Сравнение всегда верно из-за ограниченного диапазона типов данных [-Wtype-limits]

для следующего кода [попробовать в Интернете]:

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");
}
</bool,></int,></t,></typename></std::size_t></t></std::size_t>

Я понимаю, почему предупреждение будет происходить в контексте нормального выражения, например. когда я использовал бы следующую функцию validate:

template <typename t,="" std::size_t="" n="">
bool validate(T value) {
 return static_cast<std::size_t>(value) < N;
}
</std::size_t></typename>

- Фактически, именно поэтому я использую специализированный шаблон в первую очередь (и обратите внимание, что используется правильная специализация шаблона, а ошибка в моем первом коде повышается аргументом шаблона, а не внутри функции в неспециализированный шаблон). Есть ли способ обойти это предупреждение? Если нет, это не ошибка в компиляторе?

3 ответа

Это было исправлено в соединительной линии GCC, см. PR 11856

Итак, подождите примерно в конце апреля и используйте GCC 4.8: -)


Так как я не могу дождаться, пока это не будет исправлено (см. ответ Джонатанса). Ive выборочно отключил предупреждение, используя расширения GCC #pragma:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
static_assert(validator<bool, 2="">::validate(true), "Invalid");
#pragma GCC diagnostic pop
</bool,>

Обратите внимание, что эти прагмы, к сожалению, должны окружать вызывающий код, даже если фактическая ошибка возникает в параметре шаблона.


Здесь обходной путь:

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;
 }
};
</t,></typename></t></std::size_t>

Это позволяет компилировать пример без ошибок в GCC 4.7.2.

licensed under cc by-sa 3.0 with attribution.