I was reading through Infinity not constexpr, which seems to indicate that creating infinity is undefined behavior:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
However, if std::numeric_limits::is_iec559
equals true, it seems to give us more guarantees.
The code below makes use of this guarantee in order to create an infinite number. When executed in constexpr
context, it results in a compiler failure as this is undefined behavior
in case is_iec559
equals false.
// clang++ -std=c++17 -O3
#include <limits>
constexpr double createInfinity()
{
static_assert(std::numeric_limits<double>::is_iec559, "asdf");
double d = 999999999999;
while (d != std::numeric_limits<double>::infinity())
{
d *= d;
}
return -1*d;
}
static_assert(createInfinity() == std::numeric_limits<double>::infinity(), "inf");
As this function always results in infinite, it can never be called in a valid C++ program. However, as we assert on the is_iec559
, we get extra guarantees. Is this program still invalid?
- If Invalid? What's the point of having
is_iec559
? - If Valid? Why would it be valid at runtime and not in constexpr context?
(Answers can use both C++17 as the upcoming C++20, please clearly indicate which is used)