Фиксация “сравнения всегда является ложью …” предупреждение в GCC

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

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

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

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

Кто-то может дать мне решение этого?

Удачи!

5
задан Goz 29 June 2010 в 11:06
поделиться

3 ответа

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

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;
}
5
ответ дан 18 December 2019 в 14:42
поделиться

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

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>();

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

2
ответ дан 18 December 2019 в 14:42
поделиться

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

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

//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>() );
}

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

3
ответ дан 18 December 2019 в 14:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: