Calling std::min()
with an empty initializer list usually does not compile (all the question can be stated in the same way for std::max()
).
This code:
#include <iostream>
#include <algorithm>
int main() {
std::cout << std::min({}) << "\n";
return 0;
}
With clang gives this error:
test.cpp:6:17: error: no matching function for call to 'min'
std::cout << std::min({}) << "\n";
^~~~~~~~
algorithm:2599:1: note:
candidate template ignored: couldn't infer template argument '_Tp'
min(initializer_list<_Tp> __t)
I can see why this case would not be allowed, because it is difficult to agree on a sensible value to return in this case.
However, technically speaking the code does not compile only because the template parameter cannot be deduced. If I force the parameter the code compiles but I get a crash:
#include <iostream>
#include <algorithm>
int main() {
std::cout << std::min<int>({}) << "\n";
return 0;
}
$ clang++ -std=c++11 test.cpp -o test
$ ./test
Segmentation fault: 11
It seems the crash arises because std::min()
is implemented in terms of std::min_element()
, and an empty initializer list results into the dereference of an invalid end()
iterator.
So is this piece of code undefined behavior under C++11/C++14 ?
Is std::min()
stated to not compile when called without explicit template parameters?
Is std::min()
specified to be implemented in terms of std::min_element()
?
Yes, it's UB. As per C++14 (n4140) 25.4.7/4:
template <class T> constexpr T min(initializer_list<T> t);
...
4 Requires:
T
isLessThanComparable
andCopyConstructible
andt.size() > 0
.
(Emphasis mine)
The same wording is present in C++11 as well.
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