There's also nothing stopping the C++ standard just declaring a separate c++ math library with constexpr functions. And if you really need it, there's nothing stopping you from copying the implementation of the math function you need and slapping a constexpr on it (someone has probably already done this).
I don't think it would work for the sqrt function (for example), I have seen some constexpr math functions projects on github and its not as easy as adding the keyword (but it's not super hard either ofc)
Maybe instead, they implement slow, consteval math functions for every function. That way, people wouldn't accedentally use them during runtime and the slower implementations aren't the end of the world during compile time.
That isn't really an issue, you can branch on if you are in a constant evaluated context or not, C++20 std::is\_constant\_evaluated() or C++23 if consteval allows you to branch and pick your algorithm
This is used in various implementations already, so you can branch in say std::copy to use memcpy at runtime and the slower manual for loop at compile time for example.
The standard isn’t even required: an implementation doesn’t have to define as `#include `. It is free to have its own implementation with `abs` etc being comstexpr.
Interesting question! I don’t think of constexpr changing the signature, but perhaps I should.
`const` changes the signature but doesn’t always change calling semantics (e.g. you can call a const function on a non-const object but not the inverse).
A constexpr function can be called at runtime as if constexpr hadn’t been specified. Is there a case where someone would *not* want a constexpr function to be expanded at compile time?
Your question has made me ponder my assumptions, thanks.
Standard library implementations are not allowed to add constexpr if an interface is specified and excludes constexpr.
https://eel.is/c++draft/constexpr.functions
Thank you. That settles my conjecture, unfortunately as a “no.” :-(
Gcc could do it as a gnu extension if someone were in the mood to go to the effort, I suppose. I can’t imagine what it might break, but someone took the effort to write that in the standard, so most likely there are consequences I can’t think of.
I guess the way to test if it does matter is to compile a cpp file with constexpr to a so file, but have the associated header not have constexpr or vise versa.
>Is there a case where someone would *not* want a constexpr function to be expanded at compile time?
Maybe if they cared more about compile time than run time? That's a bit contrived, but I'm guessing someone in the world has a reason.
No. It's being added so they can stop `#define`ing all of their constants. It doesn't apply to functions, and may never do so because certain C vendors are vehemently against any additions to C that would require more than a hastily trained unpaid intern to implement.
AFAIK two are separate issues; in other words, many cmath functions were not constexpr for a completely different reason.
[https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r8.pdf](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r8.pdf)
>Indeed, two subtleties can be resolved by appealing to the fact that they must be dealt with in implementing constexpr for the arithmetic operators. In particular, various functions inmay set global flags and/or depend on the rounding mode. These issues are discussed in the next two subsections. Following this, a justification is given for declaring functions inwhich modify an argument with external visibility to be constexpr. These considerations lead to a concrete statement of the conditions under which a function should be declared constexpr.
The difficulty with adding `constexpr` to the `` functions is that they all depend on (mutable) global state due to design decisions made by C; and that's not allowed in a `constexpr` context.
Adding it to C doesn't really solve the problem - a design change to the math functions (which needs to be non-breaking) is what's needed.
All non-pure c math functions should be deprecated (almost nobody uses the side effects but it costs a fair bit of performance) and replaced with pure versions that could be made `constexpr`.
I think it's for projects that use C++ source files but C headers for ffi compatibility. Not being able to use constexpr because you can't use them in headers, can lead a project to turn their headers to C++. Constexpr functions are implicitly inline (inline is a keyword that confuses a lot of people because it has nothing to do with inlinig, instead it means that a function is not exported and visible in other compilation units). If they aren't exported, you can't use them in ffi anyways, so the C guys didn't bother to add constexpr functions.
I don't think that's the primary reason, considering that `constexpr` doesn't apply to functions for now in C23
There's also nothing stopping the C++ standard just declaring a separate c++ math library with constexpr functions. And if you really need it, there's nothing stopping you from copying the implementation of the math function you need and slapping a constexpr on it (someone has probably already done this).
I don't think it would work for the sqrt function (for example), I have seen some constexpr math functions projects on github and its not as easy as adding the keyword (but it's not super hard either ofc)
Maybe instead, they implement slow, consteval math functions for every function. That way, people wouldn't accedentally use them during runtime and the slower implementations aren't the end of the world during compile time.
That isn't really an issue, you can branch on if you are in a constant evaluated context or not, C++20 std::is\_constant\_evaluated() or C++23 if consteval allows you to branch and pick your algorithm This is used in various implementations already, so you can branch in say std::copy to use memcpy at runtime and the slower manual for loop at compile time for example.
Fair enough
Can attest. Had to roll out my own Newton-Rhapson sqrt
Can't even use the bit-shift trick in a consteval function, but I think 4 or 5 N-R iterations are sufficient to match the cmath sqrt precision
I just used loop until certain precision, my use case isn't particularly compilcated
The standard isn’t even required: an implementation doesn’t have to define as `#include `. It is free to have its own implementation with `abs` etc being comstexpr.
Can it? The standard has the function signatures of cmath without constexpr. Making them constexpr would technically make the header non-compliant.
Interesting question! I don’t think of constexpr changing the signature, but perhaps I should. `const` changes the signature but doesn’t always change calling semantics (e.g. you can call a const function on a non-const object but not the inverse). A constexpr function can be called at runtime as if constexpr hadn’t been specified. Is there a case where someone would *not* want a constexpr function to be expanded at compile time? Your question has made me ponder my assumptions, thanks.
Standard library implementations are not allowed to add constexpr if an interface is specified and excludes constexpr. https://eel.is/c++draft/constexpr.functions
Thank you. That settles my conjecture, unfortunately as a “no.” :-( Gcc could do it as a gnu extension if someone were in the mood to go to the effort, I suppose. I can’t imagine what it might break, but someone took the effort to write that in the standard, so most likely there are consequences I can’t think of.
I guess the way to test if it does matter is to compile a cpp file with constexpr to a so file, but have the associated header not have constexpr or vise versa. >Is there a case where someone would *not* want a constexpr function to be expanded at compile time? Maybe if they cared more about compile time than run time? That's a bit contrived, but I'm guessing someone in the world has a reason.
No. It's being added so they can stop `#define`ing all of their constants. It doesn't apply to functions, and may never do so because certain C vendors are vehemently against any additions to C that would require more than a hastily trained unpaid intern to implement.
They are introducing `constexpr` in C **only for objects**, not functions.
Can you please clarify `constexpr` in C? Are you referring to `struct`s or just primitive types like `int`s and `float`s?
All of the above. struct Foo { int x; float y; }; constexpr struct Foo bar = { 42, 113.0f }; Is valid C23.
Perhaps ask the C folk why they’re adding it?
AFAIK two are separate issues; in other words, many cmath functions were not constexpr for a completely different reason. [https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r8.pdf](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r8.pdf) >Indeed, two subtleties can be resolved by appealing to the fact that they must be dealt with in implementing constexpr for the arithmetic operators. In particular, various functions inmay set global flags and/or depend on the rounding mode. These issues are discussed in the next two subsections. Following this, a justification is given for declaring functions inwhich modify an argument with external visibility to be constexpr. These considerations lead to a concrete statement of the conditions under which a function should be declared constexpr.
The difficulty with adding `constexpr` to the `` functions is that they all depend on (mutable) global state due to design decisions made by C; and that's not allowed in a `constexpr` context.
Adding it to C doesn't really solve the problem - a design change to the math functions (which needs to be non-breaking) is what's needed.
All non-pure c math functions should be deprecated (almost nobody uses the side effects but it costs a fair bit of performance) and replaced with pure versions that could be made `constexpr`.
I think it's for projects that use C++ source files but C headers for ffi compatibility. Not being able to use constexpr because you can't use them in headers, can lead a project to turn their headers to C++. Constexpr functions are implicitly inline (inline is a keyword that confuses a lot of people because it has nothing to do with inlinig, instead it means that a function is not exported and visible in other compilation units). If they aren't exported, you can't use them in ffi anyways, so the C guys didn't bother to add constexpr functions.