gnu gccコンパイラが発行したコードを調べると、どのデストラクタが実行されるかに関する情報が、コードフォームIDで「保存」されていることが判明しました。その情報を取り戻すのは難しいです。
実装は異なる可能性があり、コードはプロセッサインスタンスのアドレスと共にデストラクタコードのアドレスをリターンアドレスとしてプロセッサスタックにプッシュしている可能性があります。
私は努力を断念する準備ができましたが、別のハッキールートが見つかりました。
私はgnuコンパイラが16バイトの境界でスタック上の構造体を整列させることに気付きました。 私の構造は8バイトなので、8未使用のバイトがあります。 だから私はスタックに割り当てられたオブジェクトを追跡するためにそれらを使用できると思った。 コンパイルフラグに応じて、-m64、-mx32などの変更や変更が必要です。
どのようにしても、私はコードをコンパイルして-m64と-mx32の両方のモードでコンパイルして動作させることができました。
純粋な "C++"(まったく逆)ではありませんが、コードが動作し、意図した効果があります。
#include <stdio.h>
#define ONSTACK(x) (((size_t)x)&0xf0000000)==0xf0000000
struct A;
void* P=nullptr;
struct A{
static int i;
long long a;
A(){
if(ONSTACK(this)){
*(void**)(this+1)=P;
P=(void*)(this+1);
}
printf("this=%p\n",this);
a=0x1111111111111111*i;i++;
}
~A(){
if(ONSTACK(this))
P=*(void**)(this+1);
*(void**)(this+1)=nullptr;
a=0xFFFFFFFFFFFFFFFF;}
};
int A::i=0xA;
void* p;
void r1(){
A x;int xx=0x66666666;
A y;int yy=0x77777777;
A z;int zz=0x88888888;
int b=0x2222222222222222;
printf("hello world %p\n",&b);
for(void* i=P;i!=nullptr;i=*(void**)i){
printf("a=%llX\n",(((A*)i)-1)->a);
}
}
void r2(){
long long r2a;
r2a=0x3333333333333333;
r1();
}
A A0;
int main(int argc, char **argv)
{ int i;p=(char*)&i-0x100;
printf("sizeof(P)=%i\n",sizeof(P));
r2();
}
「私のプログラムではガベージコレクタがあります」 - 停止します。これはすでにエラーです。 C++はガベージコレクションを不要にするRAIIを使用しています。 JavaとC#はガベージコレクションを持っていますが、それもエラーです。しかし、それを修正するにはあまりにも遠すぎます。 –