With GCC 9.1, when calling std::numeric_limits's functions with floating-point types, they return 0 in most cases.
This happens in a project I'm working on, and there is no issue with MSVC, GCC 8.3 or Clang 8.0. <double>::epsilon()
sometimes has a correct value, but when called from other files it may evaluate to 0 as well.
// Commented values at the end of the lines are the values given by the debugger
// Making the variable constexpr doesn't change their values
auto intMax = std::numeric_limits<int>::max(); // {int} 2147483647
auto floatMax = std::numeric_limits<float>::max(); // {float} 0
auto floatEpsilon = std::numeric_limits<float>::epsilon(); // {float} 0
auto floatMin = std::numeric_limits<float>::min(); // {float} 0
auto floatLowest = std::numeric_limits<float>::lowest(); // {float} -0
auto doubleMax = std::numeric_limits<double>::max(); // {double} 0
auto doubleEpsilon = std::numeric_limits<double>::epsilon(); // {double} 2.2204460492503131e-16
auto doubleMin = std::numeric_limits<double>::min(); // {double} 0
auto doubleLowest = std::numeric_limits<double>::lowest(); // {double} -0
std::cout << std::setprecision(10) << std::fixed
<< "Max int = " << std::numeric_limits<int>::max()
<< "\n"
<< "\nMax float = " << std::numeric_limits<float>::max()
<< "\nEpsilon float = " << std::numeric_limits<float>::epsilon()
<< "\nMin float = " << std::numeric_limits<float>::min()
<< "\nLowest float = " << std::numeric_limits<float>::lowest()
<< "\n"
<< "\nMax double = " << std::numeric_limits<double>::max()
<< "\nEpsilon double = " << std::numeric_limits<double>::epsilon()
<< "\nMin double = " << std::numeric_limits<double>::min()
<< "\nLowest double = " << std::numeric_limits<double>::lowest() << std::endl;
(The <int>::max()
is left as a reference here)
Result in an independent file (correct values):
Max int = 2147483647
Max float = 3.40282e+38
Epsilon float = 1.19209e-07
Min float = 1.17549e-38
Lowest float = -3.40282e+38
Max double = 1.79769e+308
Epsilon double = 2.22045e-16
Min double = 2.22507e-308
Lowest double = -1.79769e+308
Result in the project:
Max int = 2147483647
Max float = 0
Epsilon float = 0
Min float = 0
Lowest float = -0
Max double = 0
Epsilon double = 2.22045e-16
Min double = 0
Lowest double = -0
When compiling a dedicated file indepentenly, the values are correct: the issue is then not from GCC (as I expected anyway), but most likely from the project's configuration.
EDIT: compiling a project's file (on which this issue occurs at the moment) independently gives correct results as well. With gcc -dM -E
, the __DBL_MAX__
is defined to double(1.79769313486231570814527423731704357e+308L)
.
The __DBL_MAX__
value is defined, code surrounded by an ifdef is executed:
#ifdef __DBL_MAX__
#pragma message "__DBL_MAX__ defined"
#endif
/*
note: #pragma message: __DBL_MAX__ defined
40 | #pragma message "__DBL_MAX__ defined"
| ^~~~~~~~~~~~~~~~~~~~~
*/
GDB gives the same exact value, so no problem on the output part. Outputting XXX_YYY
or __XXX_YYY__
gives the same results, since numeric_limits' functions call them anyway.
To be 100% clear: std::numeric_limits<double>::max() == 0
returns true, so there is no problem on the output part. It is just left here as a reference.
What could be the reason(s) GCC produces such behavior? Aren't __XXX_YYY__
built-in values anyway? How can they possibly hold 0?