How to cast a function pointer to a void* a slightly-too-long-for-twitter report about a subtlety in C++
Question: How do you cast a function pointer to a void*? (You’re trustworthy and wouldn’t dare to do anything evil with it, right?)
Answer: Maybe your first thought was, well
reinterpret_cast<void*>(&f) of course. That was mine, at least. Well, it turns out, C++ wants to support architectures, where data and instruction pointers are physically distinct things. That’s why the standard forbids casting of function pointers to data pointers.
Many compilers will accept it anyhow and just emit a warning, but there’s a trick, which doesn’t rely on compiler specifics: A reference to a function pointer is a data reference (because of course a function pointer itself is data, even if it’s pointing to instructions) and thus it can be cast to
void*&, which in turn can be assigned to a
That brings us to our final answer:
auto fptr = &f; void *a = reinterpret_cast<void *&>(fptr);
Just be so kind as to only use it for comparison, as key in a hash map or similarly innocent things. Do not dereference it or you will enter the myth-enshrouded lands of undefined behavior.
P.S. There are two caveats to be made:
1. Even though this is guaranteed to work with all standard-compliant compilers, it’s not guaranteed to be safe on all platforms. On machines with Harvard architecture, the size of a function pointer often differs from the size of a
void* (e.g. 16bit on the Arduino One). So, especially if you’re developing for micro controllers, double check before using this trick.
2. This is about pointers to _free_ functions. Pointers to member functions are strange creatures and, even on Von-Neumann architectures, don’t have the size of
void*. It’s not possible to squeeze a PMF into a
void*. (I’m happy to stand proven wrong).
blogs.msdn.microsoft.comPointers to member functions are very strange animals. Warning: The discussion that follows is specific to the way pointers to member functions are implemented by the Microsoft Visual C++ compiler. Other compilers may do things differently. Well, okay, if you only use single inheritance, then pointers to member functions are just a pointer to the…