Вызов указателя функции-члена C++: this-pointer поврежден

мне нужно преобразовать некоторые указатели функций-членов в указатели void*(потому что мне нужно поместить их в стек Lua, но проблема не связана с Lua).

Я делаю это с помощью union. Но когда я преобразовываю указатели функций-членов в void*и обратно, а затем пытаюсь вызвать указатель с экземпляром класса, указатель thisповреждается. Как ни странно, этой проблемы не возникает, если я преобразовываю указатель void*обратно в указатель функции в стиле C с указателем на класс в качестве первого параметра.

Вот фрагмент кода, демонстрирующий проблему:

#include <iostream>
using namespace std;

class test
{
    int a;

    public:
        void tellSomething ()
        {
            cout << "this: " << this << endl;
            cout << "referencing member variable..." << endl;
            cout << a << endl;
        }
};

int main ()
{
    union
    {
        void *ptr;
        void (test::*func) ();
    } conv1, conv2;

    union
    {
        void *ptr;
        void (*func) (test*);
    } conv3;

    test &t = *new test ();

    cout << "created instance: " << (void*) &t << endl;

    // assign the member function pointer to the first union
    conv1.func = &test::tellSomething;

    // copy the void* pointers
    conv2.ptr = conv3.ptr = conv1.ptr;

    // call without conversion
    void (test::*func1) () = conv1.func;
    (t.*func1) (); // --> works

    // call with C style function pointer invocation
    void (*func3) (test*) = conv3.func;
    (*func3) (&t); // --> works (although obviously the wrong type of pointer)

    // call with C++ style member function pointer invocation
    void (test::*func2) () = conv2.func;
    (t.*func2) (); // `this' is the wrong pointer; program will crash in the member function

    return 0;
}

Вот результат:

created instance: 0x1ff6010
this: 0x1ff6010
referencing member variable...
0
this: 0x1ff6010
referencing member variable...
0
this: 0x10200600f
referencing member variable...
zsh: segmentation fault (core dumped)  ./a.out

Это ошибка в компиляторе (GCC)? Я знаю, что это преобразование между void*и указателями функций (членов) не соответствует стандарту, но странно то, что оно работает при преобразовании void*в стиль C указатель функции.

5
задан Alfred Krohmer 11 June 2012 в 09:23
поделиться