DMDはmain関数(not _Dmain)を実行する前になにをするのか
たとえば自前で pragma(crt_constructor)
とか使った場合にどういう順で実行されるんだろう、とか。
こういうコードを用意して、
enum body = "import std.stdio;writeln(__PRETTY_FUNCTION__);"; pragma(crt_constructor) extern (C) void crt_constructor() { mixin(body); } void main() { mixin(body); }
一応環境
$ dmd --version| head -1 DMD64 D Compiler v2.090.1 $ uname -mrsv Linux 4.15.0-76-generic #86-Ubuntu SMP Fri Jan 17 17:24:28 UTC 2020 x86_64
コンパイルして .init_array
セクションをみてみるとこんな感じ。
$ dmd hoge.d $ LANG=C readelf -Wx .init_array ./hoge Hex dump of section '.init_array': 0x00291dd0 70590400 00000000 70530400 00000000 pY......pS...... 0x00291de0 7c530400 00000000 f0d80600 00000000 |S.............. 0x00291df0 bcfb0600 00000000 54fc0600 00000000 ........T.......
適当にアドレスひっかけて(リトルエンディアンなことに注意)、nmコマンドでシンボルをひいてみる。
一番最初のやつは .init_array の先頭を表すやつ。
$ nm ./hoge| grep 291dd0 0000000000291dd0 t __init_array_start
他のやつは関数ポインタっぽいやつ。frame_dummyはgccが入れてるやつ。
$ nm ./hoge| grep 00045370 0000000000045370 t frame_dummy $ nm ./hoge| grep 0004537c 000000000004537c t 000000000004537c W crt_constructor $ nm ./hoge| grep 0006fbbc 000000000006fbbc t 000000000006fbbc W _d_register_conservative_gc $ nm ./hoge| grep 0006d8f0 000000000006d8f0 t 000000000006d8f0 W _d_register_manual_gc $ nm ./hoge| grep 0006fc54 000000000006fc54 W _d_register_precise_gc
こうしてみると基本はユーザ定義のやつがGCの初期化処理より先に呼ばれるので、GC使うコードは書けないはず。リンク順に依存してしまうので絶対ではないだろうけど。