5

Is main really the first function or first executable statement in a C program? What if there is a global variable int a=0;?

I have always been taught that main is the starting point of a program. But what about global variable which is assigned some value and is an executable statement in my opinion?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Harsha
  • 323
  • 1
  • 17
  • 1
    You need to understand/read what's the difference between something which will be initialized and what has to do with the execution itself. Remove main and see what happens – Michi Jun 02 '16 at 14:20
  • Any way, the OP got a lot of good answers, but the question is clearly only about he's global variable and main function. Which one will be first executed. – Michi Jun 02 '16 at 14:42

6 Answers6

10

The global variable and in general objects of static storage duration are initialized conceptually before program execution.

C11 (N1570) 5.1.2/1 Execution environments:

All objects with static storage duration shall be initialized (set to their initial values) before program startup.

Given a hosted environment, function main is designated to be an required entry point, where program execution begins. It may be in one of two forms:

int main(void)
int main(int argc, char* argv[])

where parameters' names does not need to be the same as above (it is just a convention).

For a freestanding environment entry point is implementation-defined, that's why you can sometimes encounter void main() or any different form in C implementations for embedded devices.

C11 (N1570) 5.1.2.1/1 Freestanding environment:

In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined.

Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
  • an i right? main is always the starting point the only possibility to change this would be to write a own compiler? – wake-0 Jun 02 '16 at 13:06
  • 5
    @KevinWallis the C standard defines the starting point for execution of a program in a "hosted" environment to be the `main()` function. That is where execution will start in such an environment if the program and host conform to the standard. In fact, however, some existing compilers / linkers do have options to specify a different entry point. The GNU toolchain offers such an alternative, for example. Using it renders the program non-conforming in that respect, but that doesn't mean it won't work. – John Bollinger Jun 02 '16 at 13:13
6

main is not a starting point of the program. The starting point of the program is the entry point of the program, which is in most cases is transparent for a C programmer. Usually it is denoted by _start symbol, and defined in a startup code written in assembly or precompiled into a C runtime initialization library (like crt0.o). It is responsible for low-level initialization of stuff you are taking as given, like initializing the uninitialized static variables to zeros. After it is done, it is calling to a predefined symbol main, which is the main you know.

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
  • Thank you. I would like to know more on crt0.o. Could you please provide any link or useful sites for this topic? – Harsha Jun 02 '16 at 13:30
  • There is a link, if you look closer :) Also you might want to examine an alternative startup file like [here](https://community.arm.com/docs/DOC-8769) – Eugene Sh. Jun 02 '16 at 13:36
5

But what about global variable which is assigned some value and is an execuatable statement in my opinion

Your opinion is wrong.

In a global context, only a variable definition can exist, with an explicit initialization. All the executable statements (i.e, the assignment) have to reside inside a function.

To elaborate, in global context, you cannot have a statement like

int globalVar;
globalVar = 0;  //error, assignement statement should be inside a function

however, the above would be perfectly valid inside a function, like

int main()
{
   int localVar;
   localVar = 0;  //assignment is valid here.

Regarding the initialization, like

int globalVar = 0;

the initialization takes place before start of main(), so that's not really the part of execution, per se.

To elaborate the scenario of the initialization of a global variable, quoting the C11, chapter 6.2,

If the declarator or type specifier that declares the identifier appears outside of any block or list of parameters, the identifier has file scope, which terminates at the end of the translation unit.

and for flie scope variables,

If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

and for objects with external linkage,

An object whose identifier is declared without the storage-class specifier _Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • What if I have a global variable initialized by a function call like `int i = function();`? – Carlo Jun 02 '16 at 13:08
  • 5
    @CarloCe this won't compile in C, where all initializers must be constant expressions. – Quentin Jun 02 '16 at 13:09
  • 3
    it s a pity that downvoters don't leave a comment thus depriving others of some learning opportunity. – sjsam Jun 02 '16 at 13:23
  • @Thanks Sourav. What about int i = 0 outside the main function? – Harsha Jun 02 '16 at 13:24
  • @Vrajendrav.t. That's an initialization, and global variable initialization are done before the start of `main()`. – Sourav Ghosh Jun 02 '16 at 13:25
  • @Sourav. That was exactly my question. Whether main is the first execution statement or any other; in this case int i = 0. – Harsha Jun 02 '16 at 13:27
  • 1
    That is initialization, not execution. – Mirakurun Jun 02 '16 at 13:32
  • 2
    @Vrajendrav.t. A global `int i = 0;` executes no code in C! Initialisation happens at compile time. – Konrad Rudolph Jun 02 '16 at 13:32
  • @KonradRudolph BSS nullification is happening in a startup code. but yes, there is no "statement" executing this line. It's just a loop over all of the section writing zeros. – Eugene Sh. Jun 02 '16 at 13:51
  • @Vrajendrav.t. From a very broad prespective, looking at the only C code, yes, _execution_ starts from `main()`, as no _executable_ statement can be present in the global scope, as I already mentioned. – Sourav Ghosh Jun 02 '16 at 14:01
0

In a theoretical, C-standards-only program, it is.

In practice, it's usually more involved.

On Linux, AFAIK, the kernel loads your linked image into the a reserved address space and first calls the dynamic linker that the executable image specifies (unless the executable is compiled statically in which case there's no dynammic linking part).

The dynamic linker can load dependent libraries, such as the C library. These libraries may register their own startup code, and so can you (on gcc mainly via __attribute__((constructorr))). (User-supplied init code is especially needed for C++ where you need to run some startup code on C++ globals that have constructors.)

Then the linker calls the entry point of your image, which is _start by default (linkers allow you to choose a different name if you want to dig that deep) which is by default supplied by the C library. _start initializes the C library an continues by calling main.

In any case, simple global initializations such as int x = 42; should get compiled and linked into your executable and then get loaded by the OS (rather than your code) all at once, as part of loading the process image so there's no need for user-supplied initialization code for such variables.

Community
  • 1
  • 1
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
0

If you use turbo c watch you would find that first global is declared and then execution of main starts that is at compile time data segment (giving memory to global and static variable) is initialized with 0. So though assignment is not possible but declaration occurs at compile time.

0

Yes, when you declare a variable memory is allocated to it at compile time until and unless you don't use heap segment (allocating memory to pointer)i.e dynamic allocation which occurs at run time. But since global got its memory from data segment section of RAM variable is allocated memory at compile time. Hope this helps.