C++ Migration Guide

Function Pointers and void*

In C there is no implicit conversion between pointer-to-function and void*. The ARM added an implicit conversion between function pointers and void* "if the value would fit." C++ 4.2 implements that rule. The implicit conversion was later removed from C++, since it causes unexpected function overloading behavior, and because it reduces portability of code. In addition, there is no longer any conversion, even with a cast, between pointer-to-function and void*.

C++ 5.0, in both compatibility mode and standard mode, now issues a warning for implicit and explicit conversions between pointer-to-function and void*. In both modes it no longer recognizes such implicit conversions when resolving overloaded function calls. Such code that currently compiles with the 4.2 compiler generates an error (no matching function) with the 5.0 compiler. If you have code that depends on the implicit conversion for proper overload resolution, you need to add a cast. For example:


int g(int);
typedef void (*fptr)();
int f(void*);
int f(fptr);
void foo()
{
    f(g);          // This line has different behavior
}

With the 4.2 compiler, the marked line in the code example calls f(void*). With the 5.0 compiler, there is no match, and you get an error message. You can add an explicit cast, such as f((void*)g), but you will get a warning because the code is invalid. You should modify your code so that you do not need to convert between function pointers and void*. Such code has never been portable, even when this conversion was allowed.

C++ does not have a "universal function pointer" corresponding to void*. With C++ on all supported platforms, all function pointers have the same size and representation. You can therefore use any convenient function pointer type to hold the value of any function pointer. This solution is portable to many, but not all, platforms. As always, you must convert the pointer value back to its original type before attempting to call the function that is pointed to. See also "Pointers to extern "C" Functions".