g++ のこれまたどうでもええ知識

C++のオブジェクトは実空間でどうのように配置されているのだろうか?とういことを調べてみた。(必要にかられて)

すくなくともCでは構造体の変数は宣言された順番に並びます。これは言語の規定。ではC++ではどうなるのか?タブンC++も宣言順に並ぶで正しいと思う。

しかし、問題はVirtual関数。こればっかりはインスタンス舞に呼ばれるものが違うのでメモリに配置しておかなければならないわけで・・・この部分に関してはさすがに実装依存のような気がします。

が、とりあえずg++でどうなってるかわかればいいので、とりあえず、次のようなプログラムを書いてみました。

class A{
public:
  int a;
  int b;
  A();
  virtual ~A();
  virtual void hoge();
};
A::A()
{
 a = 0x11111111;
 b = 0x22222222;
}
A::~A()
{
 printf("A\n");
}
void
A::hoge()
{
 printf("Ahoge\n");
}
これをアセンブラに変換します。 g++ -S t.cc でt.sを見てみると・・・コンストラクタらしきところ(g++では __1Aという名前になるようで)
__1A:
        pushl %ebp
        movl %esp,%ebp
        movl 8(%ebp),%edx
        movl $_vt$1A,8(%edx)
        movl $286331153,(%edx)
        movl $572662306,4(%edx)
とういことで、どうもメモリ上には int a int b $_vt$1A と順番に配置されるようです。ちなみに$_vt$1Aがバーチャル関数が格納されているテーブルで、sizeofを取ると12になります。 つまり基底クラスにおいては、Cと互換性があり、最初の構造体のメンバのデータは同じということになります。 では、このクラスから派生したクラスはどうなのでしょうか?ためしに次のようなクラスを作ってみました。
class B: public A{
public:
  int c;
  B();
  virtual ~B();
  virtual void hoge();
};
で同じようにアセンブラソースを出力し比較してみると int a int b $_vt$1A int c と並んでいる模様。sizeofは16ということになりました。なお、Virtual関数がないクラスはテーブルは何処にも入りません。普通のCの構造体となります。

Posted by issei

カテゴリ: 雑記