在海湾合作委员会中修复“比较总是错误......”的警告

时间:2010-06-29 11:06:41

标签: c++ templates gcc-warning

我遇到了一个问题,我确信这个问题很容易解决,但我很茫然......

我有一个执行以下代码的模板:

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

现在明显的原因是,当为无符号类型编译此代码时,GCC正在给我一个警告(由于数据类型的范围有限,比较总是假的)。我完全理解这背后的原因,我在numeric_limits检查中查看是否可以让编译器关闭它(它适用于MSVC)。在海湾合作委员会下,我得到了警告。有没有办法(没有禁用警告,我甚至不知道你是否可以使用GCC)来修复此警告?代码永远不会被调用,我会假设优化器也会将其编译出来,但我无法摆脱警告。

有人可以给我解决方案吗?

干杯!

4 个答案:

答案 0 :(得分:5)

更简单的解决方案:

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;
}

答案 1 :(得分:3)

  

有人可以给我解决方案吗?

没什么革命性的,但我通常是通过重载来做到这一点。这些方面的东西:

//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 :(得分:3)

请参阅https://stackoverflow.com/a/8658004/274937了解真实解决方案,该解决方案允许逐个取消 -Wtype-limits 警告。简而言之,只需将生成警告的每个比较包装成虚函数。

答案 3 :(得分:2)

您可以像这样专门化您的功能:

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

虽然禁用警告可能会更好。