Я нашел код этой формы в локальном проекте:
#include <iostream>
const unsigned LOWER_LIMIT = 0;
int main(int argc, char* argv[])
{
if (argc > 1) {
unsigned a = atoi(argv[1]);
if (a < LOWER_LIMIT) {
// if (a - LOWER_LIMIT > a) {
std::cerr << "lower\n";
a = LOWER_LIMIT;
}
}
}
atoi()
часть предназначена только для запуска демо и поставляется из другой частипрограммное обеспечение в реальном случае.Естественно, этот код выдает предупреждение с недавним g++ -Wall -Wextra
:
comparison of unsigned expression < 0 is always false
Сопровождающий не хочет изменять сравнение, потому что константа LOWER_LIMIT может быть изменена в будущем, и он хочет, чтобы она по-прежнему работала без изменений,Кроме того, он хочет, чтобы тип тоже был без знака.Моя первая идея подавить предупреждение -
if (a - LOWER_LIMIT > a) {
, в котором используется неподписанный нижний предел.Но это решение несколько сложно понять для некоторых людей.Я нашел другое решение:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
if (a < LOWER_LIMIT) {
#pragma GCC diagnostic pop
Это работает, но из части GCC
я предполагаю, что это не переносимое решение.
Существует ли портативное, универсальное и простое в использовании решение?Понимаете, как избежать этого предупреждения, и при этом сохраняете возможность для некоторых разработчиков просто изменять константу, не зная об этой части базы кода, где происходит сравнение?
РЕДАКТИРОВАТЬ: У меня есть шаблонное решение для этого, но оно выглядит как излишнее:
template<typename NumericTypeA, typename NumericTypeB>
typename std::enable_if<std::is_unsigned<NumericTypeA>::value &&
std::is_unsigned<NumericTypeB>::value, bool >::type
is_smaller_than(NumericTypeA a, NumericTypeB b)
{
return (a - b > a);
}
template<typename NumericTypeA, typename NumericTypeB>
typename std::enable_if<std::is_signed<NumericTypeA>::value &&
std::is_signed<NumericTypeB>::value, bool >::type
is_smaller_than(NumericTypeA a, NumericTypeB b)
{
return (a < b);
}
РЕДАКТИРОВАТЬ 2: Если компилятор обнаружит, что сравнение всегда ложно, не будет ли это необходимо длячтобы проверить следующее утверждение и обнаружить, что это нормально (также предлагается в ответе)?
if ((LOWER_LIMIT > 0) && (a < LOWER_LIMIT)) {
Такое чувство, что компилятор должен принять это без предупреждения, но, к сожалению, он предупреждает в этомслучай.