Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixing "comparison is always false ..." warning in GCC

I'm having a problem which I'm sure is simple to fix but I'm at a loss...

I have a template that performs the following code:

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

Now for, obvious reasons, GCC is giving me a warning (comparison is always false due to limited range of data type) when this code is compiled for an unsigned type. I fully understand the reasoning behind this and I put in the numeric_limits check to see if I could get the compiler to shut up about it (it worked for MSVC). Alas under GCC I get the warning. Is there any way (short of disabling the warning which I don't even know if you can do with GCC) to fix this warning? The code will never get called anyway and I would assume the optimiser will compile it out as well but I can't get rid of the warning.

Can someone give me a solution to this?

Cheers!

like image 793
Goz Avatar asked Jun 29 '10 11:06

Goz


3 Answers

Simpler solution:

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;
}
like image 129
MSalters Avatar answered Sep 26 '22 05:09

MSalters


Can someone give me a solution to this?

Nothing revolutionary, but I usually do this by overloading. Something along those lines:

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

If you can use class templates instead of function templates, you can use specialization instead of overloading. (There is no function template partial specialization, which makes specializing function templates a bit more of a hassle.)

like image 42
sbi Avatar answered Sep 23 '22 05:09

sbi


See https://stackoverflow.com/a/8658004/274937 for the real solution, which allows suppressing -Wtype-limits warnings case-by-case. In short, just wrap each comparison, which generates the warning, into a dummy function.

like image 20
valyala Avatar answered Sep 24 '22 05:09

valyala