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