What’s the best way to cast a function pointer from one type to another?

I think C/C++ are lacking a generic function pointer type, like void* as a generic object pointer type.

Generally, converting from one function pointer into another is supported, provided that you don’t call the wrong function pointer type. See [expr.reinterpret.cast]/6:

A function pointer can be explicitly converted to a function pointer of a different type.

A warning that is issued when casting one function pointer type to another is generally useful. Having such casting might cause a call to a function with the wrong signature. Such a problem might affect only a certain CPU architecture, or be noticed only with certain OS builds, so it might not be apparent after initial testing. The Standard just says unspecified, see [expr.reinterpret.cast]/6:

Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

Whether void* can be converted to function pointer type and whether it even has enough bits is implementation specific. True for Windows, though. I wouldn’t endorse Windows-specific habits for a generic problem. See
[expr.reinterpret.cast]/8:

Converting a function pointer to an object pointer type or vice versa is conditionally-supported.

Type punning with unions raises an issue with strict aliasing (What is the strict aliasing rule?), so not a good way to outsmart a compiler.

So, live with local warning suppression near your GetProcAddress calls, or in a GetProcAddess wrapper. Use reinterpret_cast.

If you’re going to use a helper function that casts one function type into another without a warning, be sure to use it only in GetProcAddress-like scenario, when you use some generic signature to temporary store function pointer, but that signature is not an actual signature — not to call a function pointer by a not intended type.

Sorry.

Leave a Comment