Skip to content

Clang will not accept a conversion from a bound pmf(Pointer to member function) to a regular method pointer. Gcc accepts this. #22495

Closed
@llvmbot

Description

@llvmbot
Bugzilla Link 22121
Resolution WONTFIX
Resolved on Nov 15, 2015 15:26
Version unspecified
OS Windows XP
Reporter LLVM Bugzilla Contributor
CC @majnemer,@DougGregor

Extended Description

This code below work and combines well on Gcc. With this code I can extract any pointer to a function so that I can have Delphi style events. But Clang reports

source_file.cpp:37:3: error: cannot cast from type 'int (A::)(int)' to pointer type 'MyProc' (aka 'int ()(void )')
__methodv(int,Xyz,int y) { return 5 + y;}
^~~~~~~~~~~~~~~~~~~~~~~~
source_file.cpp:13:49: note: expanded from macro '__methodv'
virtual void
_get_ptr##name() { MyProc aa = (MyProc)&this_t::name; void** bb = (void**)&aa; return bb; }
^~~~~~~~~~~~~~~~~~~~~
source_file.cpp:44:3: error: cannot cast from type 'int (B::
)(int)' to pointer type 'MyProc' (aka 'int (*)(void )')
__methodv(int,Xyz,int x) {
^~~~~~~~~~~~~~~~~~~~~~~~
source_file.cpp:13:49: note: expanded from macro '__methodv'
virtual void
_get_ptr##name() { MyProc aa = (MyProc)&this_t::name; void** bb = (void**)&aa; return bb; }
^~~~~~~~~~~~~~~~~~~~~
source_file.cpp:52:10: warning: unused variable 'i' [-Wunused-variable]
auto i = 5;
^
source_file.cpp:72:11: warning: unused variable 'xx' [-Wunused-variable]
void
xx = a->__get_ptr_Xyz();
^
source_file.cpp:76:10: warning: unused variable 'ff' [-Wunused-variable]
auto ff = std::bind(&decltype(b)::Abc,b);
^
source_file.cpp:61:10: warning: unused variable 'method' [-Wunused-variable]
auto method = &decltype(b)::Xyz;

// END OF ERRORS

So all it has to do is look at the pmf and just give me the pointer. Once I have the pointer everything is well. A way to silence the warnings is also helpful.

// START OF CODE
#include
#include
#include
//#include <windows.h>

using namespace std;

typedef int(MyProc)(void b);

#define __cdecl

#define __methodv(type,name,...)
virtual void* _get_ptr##name() { MyProc aa = (MyProc)&this_t::name; void** bb = (void**)&aa; return *bb; }
virtual __cdecl type name( VA_ARGS ) \

template<class resultT, class A>
struct TFunction1 {
typedef __cdecl resultT (TProc)(void,A);
TProc proc;
void* instance;
TFunction1(void* _instance, void* _proc) {
proc = (TProc)_proc;
instance = _instance;
}
inline attribute((always_inline)) resultT operator()(A a) {
return proc(instance,a);
}
};

using TNotifyInts = TFunction1<int,int>;

class A {
public:
using this_t = A;
virtual int Abc() { return 0; }
__methodv(int,Xyz,int y) { return 5 + y;}
};

class B: public A {
public:
using this_t = B;
int Abc() override { return 1; }
__methodv(int,Xyz,int x) {
//printf("dfg\n");
return 5 + x;
}
};

int main()
{
auto i = 5;
cout << "Hello world!" << endl;

A* a;
B b;
a = &b;



auto method = &decltype(b)::Xyz;


typedef int(*MyProc)(void* b);


#define __PMFX(obj,method)\
  obj , obj->__get_ptr_##method()


//MyProc xx = (MyProc)&std::remove_reference<decltype((*a))>::type::Abc;
void* xx = a->__get_ptr_Xyz();
auto MyFunc1 = TNotifyInts(__PMFX(a,Xyz));

//DWORD dw = GetTickCount();
auto ff = std::bind(&decltype(b)::Abc,b);
int x = 0;
while (x < 10000000) {
  //a->Abc();

  //(((B*)a)->*method)(1);
  //xx(a);
  MyFunc1(5);
  //ff();
  x++;
}

// std::cout << GetTickCount() - dw << "\n";

// auto f = std::bind(b.Abc)

return 0;

}

Is there any way to enable this in clang or is it a bug?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillac++portabilitywontfixIssue is real, but we can't or won't fix it. Not invalid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions