May 23, 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

May 23, 2015
>Every D program is started as if it were a C program.
Why is so necessary?

What about C++ and other languages? Does they have more then one main?

Why it's more than one main is needed? Why D apps can't start with single main?
May 23, 2015
On 23/05/2015 10:57 p.m., Suliman wrote:
>> Every D program is started as if it were a C program.
> Why is so necessary?
>
> What about C++ and other languages? Does they have more then one main?

Depends on the implementation. I believe Visual C++ does. But it is used like D's to allow it to initialize the runtime.
https://msdn.microsoft.com/en-us/library/bb918180.aspx

> Why it's more than one main is needed? Why D apps can't start with
> single main?

Oh but they can. But I guess you'll want things like the GC, module constructors ext oh and some globally initialized memory.
May 23, 2015
On Saturday, 23 May 2015 at 10:57:22 UTC, Suliman wrote:
>>Every D program is started as if it were a C program.
> Why is so necessary?

It's not actually necessary.  You could implement the `_start` function in your D program.  Here's a D program without any C runtime, D runtime, or main.

long __d_sys_write(long arg1, in void* arg2, long arg3)
{
    ulong result;

    asm
    {
        "syscall"
        : "=a" result
        : "a" 1,
        "D" arg1,
        "S" arg2,
        "m" arg2,
        "d" arg3
        : "memory", "cc", "rcx", "r11";
    }

    return result;
}

extern(C) void __d_sys_exit(long arg1)
{
    asm
    {
        "syscall"
        :
        : "a" 60,
        "D" arg1,
        : "memory", "cc", "rcx", "r11";

    }
}

extern(C) void _start()
{
    // you could put this in a main function and
    // call main() from here.
    auto text = "Hello, World!\n";
    __d_sys_write(1, text.ptr, text.length);

    __d_sys_exit(0);
}

Compile with:
gdc -fno-emit-moduleinfo -nostartfiles test.d

This produces a 733 byte "Hello World" binary.  -fno-emit-moduleinfo will prevent the compiler from generating a lot of auxiliary code that's not needed for this program.  -nostartfiles will prevent the C runtime from being linked in.

This is a nice little experiment, but once you start trying to use structs, classes, arrays, exceptions, or any other feature of D, you will need more and more of the D runtime.

There may also be some things generated by GDC that get called implicitly by the C runtime's initialization procedures (e.g. _init, _fini, etc..) but I'm not that knowledgeable about the compiler's codegen.

>
> What about C++ and other languages? Does they have more then one main?

C++ is a superset of C, so in my experience, C++ only needs C main.  However, C++ has static constructors that get called by some of the initialization procedures in the C runtime before actually calling main.  I wonder if C++ free functions mangled in C++...I'm not sure.

>
> Why it's more than one main is needed? Why D apps can't start with single main?

I don't think the current implementation is necessary.  There are probably many different ways to implement D program initialization.  I don't see why D runtime couldn't just implement _start, omit the C runtime altogether, and do everything in D, but I trust the compiler implementers have their reasons.

If you're interested in digging deeper, you'll probably have to ask questions on D.GNU to get the attention of the compiler implementers.

Mike

May 23, 2015
On Saturday, 23 May 2015 at 10:57:22 UTC, Suliman wrote:
>>Every D program is started as if it were a C program.
> Why is so necessary?
>
> What about C++ and other languages? Does they have more then one main?
>
> Why it's more than one main is needed? Why D apps can't start with single main?

You could have obtained answer long time ago by using debugger and looking into sources of druntime at github.
1 2
Next ›   Last »