Search code examples
c++type-conversionfunction-pointers

Interesting problem about function pointer casting


I have made a interesting test about function pointer cast:

typedef bool (*BFUNC)(int n);
typedef int  (*IFUNC)(int n);
typedef double (*DFUNC)(int n);

void vfunc(int n)
{
    n++;
}

int _tmain(int argc, _TCHAR* argv[])
{
    BFUNC f = (BFUNC)vfunc;
    IFUNC f2 = (IFUNC)vfunc;
    DFUNC f3 = (DFUNC)vfunc;

    bool bRet = f(0);
    int nRet = f2(0);
    double dRet = f3(0);

    printf("bRet=%d, nRet=%d\n", bRet, nRet); // bRet=1, nRet=1

    return 0;
}

The first interesting thing is that this code compiles and runs fine. The second interesting thing is that I actually get the return value, which seems to be 1 at the moment. (I'm using very old VS2010, don't know if it has anything to do with it)

I want to know what happened?

I did some more experimenting, and it seems that as long as I use this C-style explicit conversion, then I'm pretty free to cast one function pointer type to another, I'm wondering if there's a practical point to this? What is its underlying principle?


Solution

  • This is the reason why C-style casts have been superseded by C++ style casts (static_cast, reinterpret_cast, ...).

    C-style casts will attempt to do any of the C++ style casts in a predetermined order. In your case, the C-style cast is equivalent to a reinterpret_cast. Therefore the casts work fine.

    By invoking the function after reinterpret_casting it to a pointer to an incompatible function signature, you are invoking undefined behavior. Any discussion about the return value is moot as this is purely undefined behavior and therefore could potentially result in anything happening.

    (But if you absolutely want to know why the return value is 1, then it might be because the n++ operation will store its result on the stack where the return value is expected to be stored. After all, this functions does not have a return value, so why should it reserve stack space for one?).