代码之家  ›  专栏  ›  技术社区  ›  Goz

修正了GCC中的“比较总是错误的…”警告

  •  5
  • Goz  · 技术社区  · 14 年前

    我有一个问题,我肯定是简单的解决,但我在茫然。。。

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

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

    现在,很明显,海湾合作委员会给了我一个警告( 由于数据类型范围有限,比较总是错误的 )当为无符号类型编译此代码时。我完全理解这背后的原因,我把数字限制检查,看看我是否可以让编译器关闭它(它为MSVC工作)。唉,在GCC下,我得到了警告。有没有什么办法(除了禁用警告,我甚至不知道你是否可以用GCC)来修复这个警告?不管怎样,代码永远不会被调用,我假设乐观主义者也会编译出来,但我无法摆脱警告。

    干杯!

    4 回复  |  直到 14 年前
        1
  •  5
  •   MSalters    14 年前

    更简单的解决方案:

    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;
    }
    
        2
  •  3
  •   sbi    14 年前

    有人能给我一个解决办法吗?

    //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
  •  3
  •   Community    7 年前

    看到了吗 https://stackoverflow.com/a/8658004/274937 对于真正的解决方案,它允许 逐个警告。简而言之,只需将生成警告的每个比较包装到一个伪函数中。

        4
  •  2
  •   JoeG    14 年前

    您可以像这样专门化您的函数:

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