I'd like to convert a constant expression function pointer to a std::uintptr_t at compile time. How can I do this?
Here's a minimal example:
#include <cstdint>
void fn() {}
int main(int argc, char** argv) {
constexpr void* ptr = (void *) fn;
constexpr std::uintptr_t idx = reinterpret_cast<std::uintptr_t>(fn);
return 0;
}
GCC 7/8/9 are currently giving me the error "conversion from pointer type to arithmetic type std::uintptr_t in a constant expression." However, my understanding was that std::uintptr_t should be able to hold any pointer type, meaning this should be able to be done in a constant expression.
Background
To give a bit of background as to why I need this, I want to (1) retrieve the address of a function pointer at compile time, (2) convert it to a std::uintptr_t, then (3) pass it as a template parameter so it can be baked into a function at compile time.
This is meant to be part of an RPC engine, similar to this code, which produces a very similar error:
#include <cstdio>
#include <cstdint>
template <std::uintptr_t FnPtr, typename Fn>
void fn_handler() {
((Fn *) FnPtr)();
}
int main(int argc, char** argv) {
auto lel = []() {
printf("Hi, fam!\n");
};
// Note that +lel is an implement 0+lel, converting
// the lambda to a fn ptr.
constexpr void* ptr = reinterpret_cast<void*>(+lel);
constexpr std::uintptr_t idx = reinterpret_cast<std::uintptr_t>(ptr);
fn_handler<idx, decltype(lel)>();
return 0;
}