Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to call casted function pointers?

In particular, will the following ever not work as expected:

typedef void(*func_p)(void*);

void foo(int* data)
    {
    printf("%i\n",*data);
    }

int main(int argc, char** argv)
    {
    func_p bar;
    int x = 42;

    bar = foo;
    bar((void*)&x);

    return 0;
    }

ie, can I rely on data pointers (void*, int*, struct baz*, but not neccesarily void(*)(void)) always being passed compatably?

like image 413
David X Avatar asked Jul 05 '10 22:07

David X


People also ask

Are function pointers safe?

Pointers to member functions in C++ This is how C++ uses function pointers when dealing with member functions of classes or structs. These are invoked using an object pointer or a this call. They are type safe in that you can only call members of that class (or derivatives) using a pointer of that type.

Can you cast function pointers?

Yes, it can. This is purpose of casting function pointers, just like usual pointers. We can cast a function pointer to another function pointer type but cannot call a function using casted pointer if the function pointer is not compatible with the function to be called.

Can we call a function using pointer?

Like variables, instructions of a function are also stored in memory and have an address. A pointer pointing to the address of a function is called function pointer. A function pointer in C can be used to create function calls to the function they point to just like a normal function.

What is the advantage of using function pointers for calling functions instead of calling function directly?

They allow you to call a function which is specified at runtime. But you have exactly the same overhead as you'd get from any other function call (plus the additional pointer indirection).


2 Answers

It's not required by the Standard that this works. The Standard requires that char* and void* have the same representation and alignment requirements, all struct pointers do so and all unions pointers do so too. While it is undefined behavior to call the casted function pointer in any case (§6.5.2.2p9), the same representation and alignment requirements give a practical guarantee that the call works (§6.2.5p27).

Other pointer types need not behave in such a way, though i haven't personally met such a machine. It's theoretically possible that an int* has a smaller sizeof than a char* for example (if int has stricter alignment requirements than char, this could be a reasonable thing to do). Under the right calling convention, on such a machine it would be practically impossible to call a casted function pointer.

like image 131
Johannes Schaub - litb Avatar answered Sep 30 '22 05:09

Johannes Schaub - litb


Unless your code targets weird ancient mainframes, for all practical purposes it will work fine. No modern machine uses different representations for different pointer types, and I don't think it's realistic that any future machine ever will. It's simply illogical and backwards, much like ones-complement arithmetic.

If you're still worried or want to satisfy language purists, follow caf's suggestion.

like image 42
R.. GitHub STOP HELPING ICE Avatar answered Sep 30 '22 03:09

R.. GitHub STOP HELPING ICE