Variadic function pointer
Is this legal?
Code:
struct Test
{
void (*ptr)(void* p, ...);
};
void myfunction(void* p, int arg1, int arg2) {}
Test test = { myfunction };
In GCC, I get a warning:
warning: initialization from incompatible pointer type [enabled by default]
warning: (near initialization for 'test.ptr') [enabled by default]
Re: Variadic function pointer
Off the top of my head, I'd say the compiler is correct. If I'm reading this correctly (I rarely, almost never use function pointers), the function pointer 'ptr' is actually a member of the struct Test. Since structs and classes are pretty much the same thing, your free standing function has the wrong type to be assigned to the member 'ptr', as it should be expecting an implicit 'this' pointer.
Again, I could be way off here...
Viggy
Re: Variadic function pointer
That observation seems reasonable MrViggy.
Re: Variadic function pointer
Visual Studio 2010 c++ compiler:
Quote:
error C2440: 'initializing' : cannot convert from 'void (__cdecl *)(void *,int,int)' to 'void (__cdecl *)(void *,...)'
1> None of the functions with this name in scope match the target type
Gcc 4.7.0:
Quote:
error: invalid conversion from 'void (*)(void*, int, int)' to 'void (*)(void*, ...)' [-fpermissive]|
Quote:
Originally Posted by MrViggy
your free standing function has the wrong type to be assigned to the member 'ptr', as it should be expecting an implicit 'this' pointer
This is incorrect since he only defined and declared a free standing function pointer, so you can assign any free standing function that matches the same prototype. For example this will compile:
Code:
#include <iostream>
using namespace std;
struct Test
{
void (*ptr)(void* p);
};
void myfunction(void* p) {}
int main()
{
Test test = { &myfunction };
return 0;
}
The typical this pointer problem people run into is trying to get c to call a c++ class member like:
Code:
#include <iostream>
using namespace std;
struct Test
{
void (*ptr)(void* p);
};
class MyClass
{
public:
void myfunction(void* p) {}
};
int main()
{
MyClass Class;
Test test = { &Class.myfunction };
return 0;
}
This will complain about the missing the class pointer
Re: Variadic function pointer
To be more elaborate about trying &Class.myfunction from my previous post. The compiler will complain about trying to form a pointer by taking the address of a bound member function.
The correct syntax is &MyClass::myfunction which will not match the free function pointer prototype as you can see the prototype for the class member pointer is void (MyClass::*)(void*) and not void (*)(void*).
Now when you declare a class member pointer that matches the class member function prototype you want to call, you still need the pointer to the class to call to use with that class member function pointer. like:
Code:
#include <iostream>
using namespace std;
class MyClass
{
public:
void myfunction(void* p) {}
};
struct Test
{
MyClass* Class;
void (MyClass::*ptr)(void* p);
void Call()
{
(Class->*ptr)(0);
}
};
int main()
{
MyClass Class;
Test test = { &Class, &MyClass::myfunction };
test.Call();
return 0;
}
This is why std::bind and std::function were made :). To hide such detail in a convenient way