自作OS用のアプリケーションでC++を使う方法を調べた。使ったコンパイラはg++で、リンカはld。C++のうちの使う機能は、シンプルにクラスと継承のみ。RTTIや例外はテストしてない。
new, delete
デフォルトのnew
, delete
で行うメモリ管理を定義する必要がある。これは単純にmalloc
, free
を使えばいいだろう。new[]
やdelete[]
も定義すること。
純粋仮想関数
純粋仮想関数を定義しても、その仮想関数はサブクラスで上書きされて呼び出されないはずなので参照されないはずだけど、テーブルでは__cxa_pure_virtual
という関数が参照される。
実際に呼び出された場合には例外を投げるとかしたほうがいいかもしれないけど、基本的には呼び出されないはずなので空の関数でいいかも。
グローバルコンストラクタ
グローバル変数でクラスのインスタンスを定義した場合、main
関数の呼び出しよりも先にそれらのコンストラクタが呼び出される必要がある。g++はそのような変数に対する初期化コードへの関数ポインタを.preinit_array
, .init_array
というセクションに、また終了処理を.fini_array
に?出力する。
そこで、リンカスクリプトでこれらのデータをデータセクションに配置して、OSがアプリケーションを呼び出す際にmain
関数の呼び出し前に呼び出してやれば良い。
リンカスクリプト:
SECTIONS { |
crt0.c
extern void (*__preinit_array_start []) (void) __attribute__((weak)); |
ただ試したところ、初期化ルーチンは.init_array
に入っていて、.preinit_array
には何が入るのか、また.preinit_array
と.init_array
の間には何を初期化する必要があるのか、また.fini_array
も空で何が入るのかわからなかった。