Hey there,

I tried to write a template that finds the smallest signed integer type that can represent a given number. To achieve that, I am computing boolean constant expressions and use them to pick the right template specializations. This produces multiple "comparison is always true/false due to limited range of data type" warnings. In this context, the warning does not make any sense, because the comparison it refers to is required to be evaluated at compile time.

You can reproduce the problem with the following code:

#include <iostream>
using std::cout;
using std::endl;

#include <limits>
using std::numeric_limits;

/**
 * Helper for IntTypeThatFits.
* Template parameters indicate whether the given number fits into 8, 16 or 32
 * bits. If neither of them is true, it is assumed that it fits 64 bits.
 */
template <bool fits8, bool fits16, bool fits32>
struct IntTypeThatFitsHelper { };

// specializations for picking the right type
// these are all valid combinations of the flags
template<> struct IntTypeThatFitsHelper<true, true, true> { typedef int8_t Result; }; template<> struct IntTypeThatFitsHelper<false, true, true> { typedef int16_t Result; }; template<> struct IntTypeThatFitsHelper<false, false, true> { typedef int32_t Result; }; template<> struct IntTypeThatFitsHelper<false, false, false> { typedef int64_t Result; };

/// Finds the smallest integer type that can represent the given number.
template <int64_t n>
struct IntTypeThatFits
{
    typedef typename IntTypeThatFitsHelper<
(n <= numeric_limits<int8_t>::max()) && (n >= numeric_limits<int8_t>::min()), (n <= numeric_limits<int16_t>::max()) && (n >= numeric_limits<int16_t>::min()), (n <= numeric_limits<int32_t>::max()) && (n >= numeric_limits<int32_t>::min())
    >::Result Result;
};


int main (int, char**)
{
cout << "42 needs " << sizeof (IntTypeThatFits<42>::Result) << " bytes." << endl; cout << "1234 needs " << sizeof (IntTypeThatFits<1234>::Result) << " bytes." << endl; cout << "123456 needs " << sizeof (IntTypeThatFits<123456>::Result) << " bytes." << endl; cout << "12345678900 needs " << sizeof (IntTypeThatFits<12345678900>::Result) << " bytes." << endl;
}


Compile it with
g++ --std=c++0x -Wtype-limits -std=c++0x

For a more detailed discussion, see http://stackoverflow.com/questions/10434640/gcc-comparison-is-always-true-due-to-limited-range-of-data-type-in-template


Thanks for your time,

Benjamin Schug

Reply via email to