Исправлено предупреждение "сравнение всегда ложно ..." в GCC - PullRequest
5 голосов
/ 29 июня 2010

У меня проблема, которую, я уверен, легко исправить, но я в растерянности ...

У меня есть шаблон, который выполняет следующий код:

T value     = d;
if ( std::numeric_limits< T >::is_signed )
{
    if ( value < 0 )
    {
        *this += _T( "-" );
        value = -(signed)value;
    }
}

Теперь по очевидным причинам GCC выдает мне предупреждение ( сравнение всегда ложно из-за ограниченного диапазона типов данных ), когда этот код компилируется для типа без знака.Я полностью понимаю причину этого и вставил проверку numeric_limits, чтобы посмотреть, смогу ли я заставить компилятор замолчать (это работало для MSVC).Увы, под GCC я получаю предупреждение.Есть ли способ (кроме отключения предупреждения, которое я даже не знаю, если вы можете сделать с GCC), чтобы исправить это предупреждение?В любом случае код никогда не будет вызван, и я предполагаю, что оптимизатор также скомпилирует его, но я не могу избавиться от предупреждения.

Может кто-нибудь дать мне решение этой проблемы?* Ура!

Ответы [ 4 ]

5 голосов
/ 29 июня 2010

Более простое решение:

template <typename T> inline bool isNegative(T value) {
  return std::numeric_limits< T >::is_signed && value < 0; // Doesn't trigger warning.
}

T value     = d;
if ( isNegative(value) ) // Doesn't trigger warning either.
{
    *this += _T( "-" );
    value = -1 * value;
}
3 голосов
/ 28 декабря 2011

См. https://stackoverflow.com/a/8658004/274937 для реального решения, которое позволяет подавлять -Wtype-limit предупреждений в каждом конкретном случае.Короче говоря, просто оберните каждое сравнение, которое генерирует предупреждение, в фиктивную функцию.

3 голосов
/ 29 июня 2010

Может кто-нибудь дать мне решение этой проблемы?

Ничего революционного, но я обычно делаю это с перегрузкой.Что-то вроде этого:

//Beware, brain-compiled code ahead!
template< bool B >
struct Bool { const static bool result = B; }

template< typename T >
void do_it(T& , Bool<false> /*is_signed*/)
{
  // nothing to do for unsigned types
}

template< typename T >
void do_it(T& value, Bool<true> /*is_signed*/)
{
    if ( value < 0 ) {
        *this += _T( "-" );
        value = -(signed)value;
    }
}

template< typename T >
void do_something(T& value)
{
  do_it(value, Bool<std::numeric_limits< T >::is_signed>() );
}

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

2 голосов
/ 29 июня 2010

Вы можете специализировать свою функцию следующим образом:

template <bool S> 
void manipulate_sign(T&) {}

template <> 
void manipulate_sign<true>(T& value) {
  if ( value < 0 )
  {
    *this += _T( "-" );
    value = -(signed)value;
  }
}

//then call like this:
manipulate_sign<std::numeric_limits< T >::is_signed>();

Хотя лучше отключить предупреждение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...