7

I know in C, before application can get started in main(), some entity must:

  1. Initialize Global variables
  2. Set the stack pointer to the lowest stack area address(assuming stack grows upward)

Question 1- What's that entity that does this stuff? Who writes it?

Question 2- Are there additional things in C++? I assume object constructors and initializations are all done during the course of application, after main()

doubleE
  • 1,027
  • 1
  • 12
  • 32
  • The dynamic linker does lots of stuff before `main` when you run a program. The OS kernel also does a bunch. – Jesper Juhl Dec 01 '18 at 12:23
  • 2
    The entity that does "this stuff" is sometimes called "startup code". It sets things up, then calls `main()`, captures the return value from `main()`, and then does any cleanup. It is normally written by the vendor who supplies your compiler and standard library, but may use code supplied by the host system. In C++, the compiler takes care of emitting code that ensures constructors of static objects at file scope are called before `main()` - and possibly other statics as well - and (ideally) their destructors are called after `main()` (in reverse order of construction). – Peter Dec 01 '18 at 12:26
  • @harper: That's a hack for C, in C++ the language has native functionality for this (Global objects with constructors) – MSalters Dec 01 '18 at 13:12
  • 1
    A lot of globals don’t actually have to have instantiation code because they are actually stored in the data section of the executable. As for the stack pointer, in a kernel that is usually 8 KiB in the bss section (statically allocated, but not set). In normal applications it is probably allocated at runtime. If you want to see the startup code disassemble the executable and look for the exported function, usually named `start`. That is the true entry point, it eventually calls main. It also calls a `crtStartup` or something in Windows. – vandench Dec 01 '18 at 16:29

3 Answers3

5

A lot depends on the execution environment. A great deal of work may be done by the operating system loader before the C run-time start up that is specifically part of your executable runs. This operating system dependent part of setting up the execution environment is common to all native (machine language) executables, regardless of source implementation language.

What part is played by the OS and what is performed by code that is part of your executable differs depending on the execution environment. The OS loader (in a non-standalone system)is responsible for loading the code into memory, and may involve loading and linking dynamically-linked libraries (DLL or shared-libraries depending on the OS nomenclature). Regardless of whether it is an OS or an C-runtime responsibility, the following normally occur:

  • Establishment of a stack
  • Zero initialisation of initialised static data
  • Initialisation of explicitly initialised static data
  • C library initialisation (typically stdio and heap-management require some initialisation)
  • For C++ call static constructors.
  • Creation of the stack frame for main() (argv, argc parameters)

In GCC and some other compilers for example, the part that is performed by your program rather then the OS prior to your program starting, is performed by a separately linked module called crt0.o. This is normally written in assembler and is automatically linked by default.

For further examples and discussion see:

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Clifford
  • 88,407
  • 13
  • 85
  • 165
3

Question 1- What's that entity that does this stuff? Who writes it?

The C compiler team writes it.

What happens is OS specific but basically it does things like deal with command line arguments, open/connect stdin, stdout, stderr, etc..

If you dig around the gcc or clang source I'm sure you can find the code1. You can pass in options to the linker to not include this code if you program doesn't need it. For example if you don't read arguments nor use files and you want to do whatever other setup yourself you can pass in arguments not to include the startup code.

Question 2- Are there additional things in C++?

Yes, there's no such thing as constructors and destructors in C so if nothing else C++ has to deal with those.

1: here's an example

gman
  • 100,619
  • 31
  • 269
  • 393
2

In this answer I have investigated the entry point location for a C program: Is main() really start of a C++ program?

When I do an analogous analysis for C++, the results are basically the same, and as others mentioned, it is part of glibc with backtrace at main:

#0  main () at hello.cpp:3
#1  0x00007ffff7be50b3 in __libc_start_main (main=0x5555555551a9 <main()>, argc=1, argv=0x7fffffffbfb8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffbfa8) at ../csu/libc-start.c:308
#2  0x00005555555550ee in _start ()

so the exact same line as that of a C program.

I think the C++ compiler is just calling into hooks to achieve any C++ specific functionality, and things are pretty well factored across C/C++.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985