Here is the test program:
void testFunc()
{
double maxValue = DBL_MAX;
double slope = std::numeric_limits<double>::quiet_NaN();
std::cout << "slope is " << slope << std::endl;
std::cout << "maxThreshold is " << maxValue << std::endl;
std::cout << "the_min is " << std::min( slope, maxValue) << std::endl;
std::cout << "the_min is " << std::min( DBL_MAX, std::numeric_limits<double>::quiet_NaN()) << std::endl;
}
int main( int argc, char* argv[] )
{
testFunc();
return 0;
}
In Debug, I get:
slope is nan
maxThreshold is 1.79769e+308
the_min is nan
the_min is 1.79769e+308
In Release, I get:
slope is nan
maxThreshold is 1.79769e+308
the_min is 1.79769e+308
the_min is nan
Why would I get a different result in Release than Debug?
I already checked Stack Overflow post Use of min and max functions in C++, and it does not mention any Release/Debug differences.
I am using Visual Studio 2015.
Got it:
Here is the implementation used by VS in Debug mode (with _Pred
being DEBUG_LT
, LT for Lower Than):
template<class _Pr,
class _Ty1,
class _Ty2> inline
_CONST_FUN bool _Debug_lt_pred(_Pr _Pred,
_Ty1&& _Left, _Ty2&& _Right,
_Dbfile_t _File, _Dbline_t _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
return (!_Pred(_Left, _Right)
? false
: _Pred(_Right, _Left)
? (_DEBUG_ERROR2("invalid comparator", _File, _Line), true)
: true);
}
Which is equivalent to (more readable):
if (!_Pred(_Left, _Right))
{
return false;
}
else
{
if ( _Pred(_Right, _Left) )
{
assert( false );
return true;
}
else
{
return true;
}
}
Which, again is equivalent to (!_Pred(_Left, _Right))
. Transcripted as a macro, it becomes #define _DEBUG_LT(x, y) !((y) < (x))
(i.e: NOT right < left).
Release implementation is actually a macro #define _DEBUG_LT(x, y) ((x) < (y))
(i.e: left < right).
So Debug (!(y<x))
and Release (x<y)
implementations are definitely not the same and they do behave differently if one parameter is a NaN...! Don't ask why they did that....