Storage of Global Variables – Best Practices in Programming

language-designlanguage-featuresmemoryprogramming-languagesstorage

In C, global variables are stored with the program code. I.e. the space to hold them is part of the object file (either in the data or bss section), instead of being allocated during execution (to either the stack or heap).

What other ways are used by languages to store global variables? For example, consider a dynamic language like Python. What about recursive languages like Lisp? Does class-orientation come into play? Do "new" languages (with the benefit of hindsight) take a different approach?

Is there any substantial benefit that C gains by storing global variables in-situ with the code?

Best Answer

No, the global variables are not necessarily stored with the code.

The C standard defines the global variables to be of static storage duration (caution: static storage duration is not to be confused with static variables, which are a subset thereof). It does not guarantee that the global variables are preallocated in the executable file, but only that:

6.2.4/3: (...) Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

A compliant C implementation could therefore perfectly well allocate and initialize global variable at runtime, as long as this is done before the programme startup.

The programme startup, by the way, is not the start of the executable process by the operating system. The C standard explains here what it is:

5.1.2/1: (...) program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified.

It is however true that many C language implementations behave like you explain. But this is not specific to C. It is related to the use of a feature offered in many operating systems, which allow to define data segments in the executable file to be loaded with pre-initialized data, the adress of which being resolved by the linker when the executable file is generated (and eventually relocated by the loader).

Related Topic