This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Bad g++ warning (type-limits) for compile-time constants


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]