Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does std::numeric_limits do for types that don't specialize it?

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_limits template. 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???"

like image 662
Enlico Avatar asked Jul 27 '26 01:07

Enlico


1 Answers

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_limits primary 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 false values unless numeric_limits is specialized for a type. - end note]

- [numeric.limits.general] p3

like image 93
eerorika Avatar answered Jul 28 '26 17:07

eerorika



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!