initializationがスマートリンクされるようになるぞ

http://blogs.embarcadero.com/abauer/2009/05/29/38888
久しぶりにいいネタ発見しました。って2か月前か……。

Delphiでは各ユニット*1毎に必要となる初期化時の処理をinitialization節に書いておくと、usesしただけでそれが実行されるようになって、いちいち使う側で初期化関数を呼ばなくて済むようになってとても嬉しいのですが、このinitialization節はスマートリンク*2を生かして.exeサイズを減らしたい立場から見るとマイナスだったわけです。

といいますのはDelphiでは慣習として、スマートリンクが行われるのを前提として、ひとつのユニットにかなりたくさんの内容を詰め込む事が行われています。#includeやpublic importと異なり、usesは連鎖しませんので、ユニットを細かく分けてしまうと、使う側のuses節が大変な事になってしまうからです。コンパイル速度が速い事や、IDEの移動機能が充実している事もこれを助けています。*3

initializationに書かれた内容は必ず実行されますので、必ずリンクされます。initializationは大抵それだけでは完結せずに、そのユニットで定義されたクラスなり関数なり変数なりを使います。初期化処理ですから当然ですね。というわけで、initialization節中で参照されたものもリンクされます。つまり、初期化処理が必要なものは、必ずスマートリンクの対象外となってしまっていたわけです。

翻訳単位を細切れにしていればそれでも問題ないのですが、先に述べましたように、Delphiの慣習ではスマートリンクを前提としてひとつのユニットに沢山詰め込みます。それにも関わらず、初期化処理が必要なものはスマートリンクされないため、ユニットの分割方針に悩むジレンマがあったわけです。

記事のclass constructorが採用されれば、実際に使用されたクラスに付随する初期化処理だけが実行されるという具合に、リンカが必要なシンボルを手繰る方向が逆になりますから、初期化処理が必要なものであってもスマートリンクの恩恵にあずかることができるようになり、ますますひとつのユニットに何も考えず沢山詰め込むスタイルが助長されてめでたしめでたし……本当にめでたいのかそれは。

*1:翻訳単位

*2:どこからも参照されてないシンボルを実行ファイルに含めないようにするリンカの機能

*3:余談ですが、Adaという言語は翻訳単位を細切れにするのが慣習ですので、同じように連鎖しないwith節が大変な事になります。どうでもいいです。