Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ISO C++ forbids casting between pointer-to-function and pointer-to-object

I want to have a class that would be able to keep as its fields a pointer to a function and a pointer to a structure holding is arguments. The interface of that object would be a method call() taking no arguments but passing saved arguments to the above mentioned function. A family of such classes for different arguments types and counts would have a common abstract ancestor with call being virtual.

As for now I have the following code which works, though adding the -pedantic option to g++ yields errors:

class Function {
    protected:
    void *data;
    void *function;
    public:
    virtual void call() = 0;
};

class SingleArgumentFunction : public Function {
    public:
    SingleArgumentFunction( void (*f)(int), int i ) {
        int *icpy = new int(i);
        function = (void*) f;
        data = (void*) icpy;
    }
    ~SingleArgumentFunction() { delete (int*)data; }
    inline void call() {
        ( *((void (*)(int))function) )( *(int*)data );
    }
};

The error I get is as the title says:

warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object

How to handle that?

like image 337
yauser Avatar asked Jan 27 '13 02:01

yauser


1 Answers

Don't cast pointer-to-function to pointer-to-object, they are not guaranteed to have the same size. You will be able to work around this issue by using a void(*)() function pointer instead.

C99 [6.2.5/27]:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

C99 [6.3.2.3/8]:

A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer.

References taken from this other SO answer.


By the way, it seems that you are trying to recreate std::function+std::bind.

std::function< void() > f;
f = std::bind( &some_function_that_takes_an_int, 42 );

f(); // look ma! no arguments
like image 194
K-ballo Avatar answered Sep 19 '22 00:09

K-ballo