一部のメンバー関数ポインターをポインターに変換する必要がありvoid*
ます (それらを Lua スタックにプッシュする必要があるためですが、問題は Lua 関連ではありません)。
を使用してこれを行いますunion
。しかし、メンバー関数ポインターを a に変換してから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 スタイルの関数ポインターに変換するときに機能します。