Edit at 10/10/2023 06:30 UTC:
Thanks to valuable comments from @DrewDormann, @Solomon Slow, @Pepijn Kramer, and @user17732522, I've come to realize that I posed a question without thorough consideration. Allow me to provide further clarification.
For a reentrant function, its result seems can be determined only by its arguments. If so, if its arguments are constant, it becomes possible to determine the result at compile-time. That is why I have the question about the relationship between reentrant and constexpr functions.
However, I made an mistake in my assumption concerning "constant arguments." While it's true that non-type template parameters are constant, it's important to note that constant arguments do not necessarily have to be template arguments.
Regarding the parameter type of std::string, we have examples of constexpr functions like the following in the latest C++ standard:
#include <iostream>
#include <string>
using namespace std;
constexpr string say_hello(string x) { return "Hello, "s + x; }
int main()
{
cout << say_hello("World") << endl;
return 0;
}
So, can any reentrant function in C++ be refactored into a constexpr function?
And thanks for the comments and answers to the original question.
Original Question
Can any reentrant function in C++ be refactored into a constexpr function template?
I learned that a function (in C) is considered reentrant when it adheres to the following rules:
Do not use static or global variables in your function since those may be changed by time your function resumes
Function must not modify its own code (e.g. some low level graphic routines may have "habit" to generate itself)
Do not call any function that does not comply with the two rules above
In C++, similar principles may apply. Then I noticed that the rules about constexpr functions is similar too.
For a reentrant function like:
float f(float x) { return x*x; }
It can be refactored into a constexpr function template in C++20:
template <float X> constexpr float f() { return X*X; }
It is a simple example. For more complex situation, however, is such a refactoring always possible? In other words, Can any reentrant function in C++ be refactored into a constexpr function template?
No: you can build tons of functions that will be completely re-entrant, but cannot be refactored into constexpr functions.
There are a ton of API's with re-entrant functions in the world, requiring just 1 of them will stop you from refactoring it as a constexpr.
On a purely theoretical level: maybe: might require re-implementing a whole lot of code.