What happens when you launch a D application ?

Mike via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat May 23 03:18:54 PDT 2015


>
> Could you explain what mean "C main inside the runtime". I 
> thought that is only one main is possible. And why it's named 
> "*ะก* main" D is not C-translated language.
>
> Same question is about _Dmain -- what is it?
>
> If I will call this() before main? What it will be? Will it run 
> before main?
>

This is a great question; one which I've tried to answer through 
my own investigation.  So, I'll add what I've learned.

Every D program is started as if it were a C program.  This is 
easiest to see with the GNU toolchain.  Try to compile a blank 
test.c file

gcc test.c
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../lib/crt1.o: 
In function `_start':
(.text+0x20): undefined reference to `main'

Now try to compile a blank test.d file

gdc test.d
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../lib/crt1.o: 
In function `_start':
(.text+0x20): undefined reference to `main'
{...and a bunch of other errors}

So, you can see that both C and D programs need to define an 
unmangled `main` symbol.  We call this symbol "C main".  DMD and 
LDC seem to add "C main" automatically, while GDC defines it in 
the D runtime:  
https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/__entrypoint.di#L60

"C main" then calls `_d_run_main`, and passes in a pointer to 
`_DMain`.  `_DMain` is actually a phony alias to your D program's 
`void main()`, so you won't find it implemented anywhere.  Your D 
program's `void main()` is D-mangled, so it is distinguishable 
from "C main".  We call this symbol "D main"
https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/__entrypoint.di#L62
https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/rt/dmain2.d#L235

_d_run_main calls `rt_init()` which does all of the D runtime 
initialization...
https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/rt/dmain2.d#L410
... and then calls `_DMain` (but it was passed into `_d_run_main 
as` `mainFunc`:
https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/rt/dmain2.d#L411

So in summary it looks like this (At least in Linux):
* Operating system calls `_start` which is defined in the C 
Runtime (crt1.o).
* _start calls the unmangled `main` which we will call "C main".  
This function is automatically added by DMD and LDC, but defined 
in GDC's D runtime.
* "C main" calls `_d_run_main` passing in a pointer to the symbol 
`_DMain`.  `_DMain` is actually your D program's `void main()` 
function.  It is D-mangled, so the linker can distinguish it from 
"C main"
* `_d_run_main` then calls `rt_init()` to initialize the runtime, 
and then calls `_DMain`.

I believe the module constructors and the static constructors are 
called in D runtime's rt_init function: 
https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/rt/dmain2.d#L152
I'm still studying how exactly that works, though.  I think they 
are linked into ModuleInfo.

I hope this is helpful.  If you want to know more about how the 
operating system calls C main (at least in a Linux environment), 
see these links:
http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html
https://gcc.gnu.org/onlinedocs/gccint/Initialization.html

Mike



More information about the Digitalmars-d-learn mailing list