...というわけで。
例のリンカエラーで苦しんでいる時にふと思い当たった。そもそもこのリンカエラーの文言は次の通りだ。
「○×から□△への参照が16ビット参照の範囲外です。」
つまり、どっかの処理から呼んでいる別の処理までのアドレス上の距離が符号付き16ビット整数の範囲内に収まっていなければならんということのようだ。つまり呼び出し地点から前後32KBの範囲までしかジャンプできないということか。狭いねぇ。では、仮想関数はどうなるのか?
仮想関数は関数テーブルを使用して実行時にバインディングを行う。この仮想関数テーブルは様々な場所から参照されるものだから、相対アドレスではなく絶対アドレスで構成されているはずだ。つまり、相対距離でのジャンプでなく、即値アドレス指定のはず。
ということは、同一セグメント内にあろうがなかろうが効率は同じと言うことになるのだろうか? すくなくとも、実距離が離れていても仮想関数テーブル経由ならば問題なくリンクできるのだろうか?
...やってみたところ、できてしまった。仮想関数経由でしか使用されないクラスのモジュールをまるごと別セグメントに移動したところ、これまでのリンカエラーの洪水が嘘のようになくなってしまったのだ。う?ん、あれだけ悩んでいたものがあっさり解決してしまった。ひょっとしたら内部的には非効率なコードになってしまったのかもしれないが、現時点では特に問題なさそうだ。

コメントする