Since C++20, there are immediate functions, whose addresses can't be taken in many cases (P1073R3); and most standard library functions are made non-addressable (P0551R3).
Also, there are some constexpr
standard function always returning the same constant value (e.g. static member functions of standard std::numeric_limits
specializations, std::barrier<F>::max
), and none of them is addressable.
Can implementations conformingly change these functions to consteval
?
I intended to make such a change in standard library implementations and opened a discussion in MSVC STL's repo, without receiving any answer so far. And I also wonder whether such change is an improvement, since it possibly reduces the size of symbol tables.
It depends on the individual function. If there are any parameters, then the answer is no:
This happens because a
consteval
function must only be called with compile-time arguments (this is an over-simplification, it's a bit more complicated) and aconstexpr
function can have parameters which exist only at runtime. See also P1938R3: ยง3.1 Interaction between constexpr and constevalThat being said,
consteval
functions with no parameters which are not explicitly addressable can be madeconsteval
, since there is no observable difference between aconstexpr
andconsteval
function invocation with no arguments. It would be a classic case of the "as-if rule". See also: What exactly is the "as-if" rule?However, it would be an ABI-break to do this retroactively. If there are existing applications that make a call to say,
std::numeric_limits<float>::max()
, this call would produce a linker error becauseconsteval
functions don't get emitted into the library. Therefore, implementers may be hesitant to modify existing functions like that. Of course, this refers to debug builds, where::max()
hasn't been inlined. See also: P2028: What is ABI, and What Should WG21 Do About It?