59

Possible Duplicate:
Why are global and static variables initialized to their default values?

See the code,

#include <stdio.h>

int a;
int main(void)
{
    int i;
    printf("%d %d\n", a, i);
}

Output

0 8683508

Here 'a' is initialized with '0', but 'i' is initialized with a 'junk value'. Why?

Community
  • 1
  • 1
yuvanesh
  • 1,093
  • 2
  • 9
  • 19
  • Closed, but the most obvious reason is not mentioned: local variables are just pointers to the stack, and the stack changes all the time. – dagelf Nov 06 '20 at 11:38

4 Answers4

128

Because that's the way it is, according to the C Standard. The reason for that is efficiency:

  • static variables are initialized at compile-time, since their address is known and fixed. Initializing them to 0 does not incur a runtime cost.

  • automatic variables can have different addresses for different calls and would have to be initialized at runtime each time the function is called, incurring a runtime cost that may not be needed. If you do need that initialization, then request it.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
  • 1
    nice answer +1,...global values are assigned `0` at compilation time na? – Grijesh Chauhan Dec 27 '12 at 05:45
  • 5
    If the global variables are not initialized to a non-zero value, they are set to zero as the process image is loaded, before the `main` program starts. That's a one-time operation, compared with an 'every time the function is called' operation for local variables. – Jonathan Leffler Dec 27 '12 at 07:03
  • 19
    actually static variables are initialized at runtime too. The C runtime (crt) will initialize them before calling main. Of course this happens only once but it still at runtime. – Sil Oct 09 '13 at 13:46
  • 12
    Also, you cannot initialize anything at compile time. The program needs to be started and loaded in memory so that you can 0 out the contents (in this case the bss section). It is impossible to that at compile time, only runtime. cheers – Sil Oct 09 '13 at 13:48
  • @Sil - from the instances that I examined you are right in your 1st comment. However, can you justify the 2nd one? Since the variables allocation is known at load time, why do you think it is not possible to have the initialization values put in the binary image, and set the variables during image load? – ysap Nov 18 '14 at 19:08
  • @ysap, it would just make the binary bigger (waste of space). But there may be a chance that at least on Windows systems pages that have already been zeroed could be used directly static objects somehow (but I don't know). – Sil Dec 17 '14 at 09:05
  • @Sil - the image IS bigger (much bigger, sometimes) anyway. It is full of loader information that is not actually loaded on the target. Also, if the statics are not initialized to "0", then the initialization values must reside in the image somewhere, so they can be copied over the statics at run-time. – ysap Dec 17 '14 at 15:45
  • This is wrong or at least not precise. 'Initialized at compile time' doen't exist. Function local variables reside in cpu registers and might be pushed on the stack. Statics and globals reside in different memory locations. Zero initialized variables don't blow up the image. They increase the size value of the .bss section which has to be zeroed at run time. – robsn Jun 05 '20 at 09:36
  • It is not entirely true to assert that initializing run-time objects to zero has no cost. Certainly in general-purpose multi-user operating systems, the system must conceal other process’ data in memory before reusing that memory for another process, and there is zero *marginal* cost in setting that new memory to zero rather than some other value. However: (a) This still takes time, and it does not always occur during process start-up; it may occur during on-demand when a page is used for the first time later during execution… – Eric Postpischil Sep 19 '21 at 11:02
  • … (b) On special-purpose systems, there might be no default overwriting/clearing of memory being newly allocated to a process since there are no other users whose data needs protecting. (c) Even on general-purpose multi-user systems, putting objects in a zero-initialized section puts them in a different location from other-initialized objects and therefore may impose cache costs greater than if the objects a program used frequently and close together in time were located close together in memory. – Eric Postpischil Sep 19 '21 at 11:05
44

global and static variables are stored in the Data Segment (DS) when initialized and block start by symbol (BSS)` when uninitialized.

These variables have a fixed memory location, and memory is allocated at compile time.

Thus global and static variables have '0' as their default values.

Whereas auto variables are stored on the stack, and they do not have a fixed memory location.

Memory is allocated to auto variables at runtime, but not at compile time. Hence auto variables have their default value as garbage.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Raghu Srikanth Reddy
  • 2,703
  • 33
  • 29
  • 42
  • 6
    That's not completely correct. .bss is not allocated during compile time, and actually this is the reason for introducting .bss as a special section for uninitialized/zero static/global variables. Only size information need to be stored and hence the binary isn't trashed with unnecessary data (i.e. zeros). At runtime, .bss variables are initialized with zero (unlike variables in the .data section, where the actual initial value _has_ to be stored within the binary). Besides that, I consider this as the better answer, +1 :-) – andreee Dec 18 '15 at 21:03
16

You've chosen simple variables, but consider:

void matrix_manipulation(void)
{
    int matrix1[100][100];
    int matrix2[100][100];
    int matrix3[100][100];

    /* code to read values for matrix1 from a file */
    /* code to read values for matrix2 from a file */
    /* code to multiply matrix1 by matrix2 storing the result in matrix3 */
    /* code to use matrix3 somehow */
}

If the system initialized the arrays to 0, the effort would be wasted; the initialization is overwritten by the rest of the function. C avoids hidden costs whenever possible.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    The effort would be wasted were they simple variables as well... – K-ballo Dec 27 '12 at 05:41
  • 2
    @K-ballo: yes, you're right — but the cost is more noticeable when the variables are largish arrays, or structures, or arrays of structures. Even a few dozen integer variables being initialized is not very noticeable, but a few thousand integer values becomes noticeable. – Jonathan Leffler Dec 27 '12 at 05:45
  • 1
    even 1 integer is noticeable (+1 instruction) if it's in an inner loop of something that only uses 4 instructions to execute. – Erik Aronesty Nov 28 '14 at 14:53
6

Global variables are allocated and initialized before the main function starts, while local variables are generated on the stack as the instance of the program runs.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
WiSaGaN
  • 46,887
  • 10
  • 54
  • 88