This code compiles and runs
#include <limits>
#include <iostream>
struct Foo {
int x;
};
static_assert(!std::numeric_limits<Foo>::is_specialized);
int main() {
std::cout << "---" << std::endl;
std::cout << std::numeric_limits<Foo>::lowest().x << std::endl;
std::cout << std::numeric_limits<Foo>::min().x << std::endl;
std::cout << std::numeric_limits<Foo>::max().x << std::endl;
std::cout << "---" << std::endl;
}
and it prints
---
0
0
0
---
Where are those numbers coming from?
On cppreference I read that
This information is provided via specializations of the
std::numeric_limitstemplate. The standard library makes available specializations for all arithmetic types
from which I'd deduce that the absence of a specialization for a given type Foo means that I'm not allowed to use it for Foo. So is the above output just a manifestation of UB? Or what?
If I change int to char in the code above, the output is
---
---
which to me is "What?! Where have the std::endls gone, to start with???"
Using the unspecialized numeric_limits is well defined. The code example has no UB. Quote from the standard draft:
... static constexpr T min() noexcept { return T(); } static constexpr T max() noexcept { return T(); } static constexpr T lowest() noexcept { return T(); } ...For the
numeric_limitsprimary template, all data members are value-initialized and all member functions return a value-initialized object.[Note 1: This means all members have zero or
falsevalues unlessnumeric_limitsis specialized for a type. - end note]
- [numeric.limits.general] p3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With