CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Aug 2008
    Posts
    902

    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]

  2. #2
    Join Date
    Feb 2002
    Posts
    4,640

    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

  3. #3
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Variadic function pointer

    That observation seems reasonable MrViggy.
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  4. #4
    Join Date
    Jun 2008
    Posts
    592

    Resolved Re: Variadic function pointer

    Visual Studio 2010 c++ compiler:
    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:
    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
    0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
    0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000
    0000 0000 0000 0000

  5. #5
    Join Date
    Jun 2008
    Posts
    592

    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
    Last edited by Joeman; December 16th, 2011 at 08:23 PM.
    0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
    0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000
    0000 0000 0000 0000

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured