How does the compiler know where in memory the square root will be before the program is executed? I thought the address would be different everytime the program is executed, but this works:
constexpr double(*fp)(double) = &sqrt; cout << fp(5.0);
Is it because the address is relative to another address in memory? I don't think so because the value of fp
is large: 0x720E1B94.
C++'s constexpr brings another new dimension to the problem too! It behaves like const in the sense that it makes all pointers constant pointers. But because it occurs at the start of your statement (rather than after the '*') its not immediately obvious.
A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.
A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.
A constexpr function is a function that can be invoked within a constant expression. A constexpr function must satisfy the following conditions: It is not virtual. Its return type is a literal type.
At compile time, the compiler doesn't know the address of sqrt
. However, you cannot do anything at compile time with a constexpr function pointer that would allow you to access that pointer's address. Therefore, a function pointer at compile time can be treated as an opaque value.
And since you can't change a constexpr variable after it has been initialized, every constexpr function pointer can be boiled down to the location of a specific function.
If you did something like this:
using fptr = float(*)(float); constexpr fptr get_func(int x) { return x == 3 ? &sqrtf : &sinf; } constexpr fptr ptr = get_func(12);
The compiler can detect exactly which function get_func
will return for any particular compile time value. So get_func(12)
reduces down to &sinf
. So whatever &sinf
would compile to is exactly what get_func(12)
would compile to.
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