You don’t want to initialize global variables

** This is not a .Net blog **

According to C-FAQs, global variables are guaranteed to start out as zero.

1.30: What am I allowed to assume about the initial values
of variables which are not explicitly initialized?
If global variables start out as “zero”, is that good
enough for null pointers and floating-point zeroes?

A: Uninitialized variables with “static” duration (that is, those
declared outside of functions, and those declared with the
storage class static), are guaranteed to start out as zero, as
if the programmer had typed “= 0”.  Therefore, such variables
are implicitly initialized to the null pointer (of the correct
type; see also section 5) if they are pointers, and to 0.0 if
they are floating-point.

Variables with “automatic” duration (i.e. local variables
without the static storage class) start out containing garbage,
unless they are explicitly initialized.  (Nothing useful can be
predicted about the garbage.)

Dynamically-allocated memory obtained with malloc() and
realloc() is also likely to contain garbage, and must be
initialized by the calling program, as appropriate.  Memory
obtained with calloc() is all-bits-0, but this is not
necessarily useful for pointer or floating-point values (see
question 7.31, and section 5).

References: K&R1 Sec. 4.9 pp. 82-4; K&R2 Sec. 4.9 pp. 85-86; ISO
Sec. 6.5.7, Sec., Sec.; H&S Sec. 4.2.8 pp. 72-
3, Sec. 4.6 pp. 92-3, Sec. 4.6.2 pp. 94-5, Sec. 4.6.3 p. 96,
Sec. 16.1 p. 386.

So initializing global variables to zero/NULL is totally unnecessasry.

Well, turns out initializing global variables to zero/NULL actually *hurts* performance, if those global variables are in a dll.

Global variables are put in the data section of a dll. The data section has Copy-On-Write semantics, meaning, when you modify data on that section, OS will make a copy of that page, and let you modify the copy. This makes sense, since the dll may be loaded into different processes, and you want every process to have different values.

If you initialize global variables, when the dll is loaded into your process, OS has to copy *some extra pages*, due to the Copy-On-Write semantics of global variables.

Maybe the compiler should be smart enough to optimize out this?

Comments (2)

  1. Uwe Keim says:

    This whole C++ thing (which I do since nearly 10 years now) is really really such a (unnecessarily) complex piece of compiler…

  2. Jay says:

    Junfeng, you are wrong in two ways.

    First, initialization to non-zero does not cause a copy-in-write — as long as it is compile-time-const.

    Second, initialization to compile-time-zero gets further optimized. The variable is put in the "uninitialized" (zero initialized) section, sometimes referred to as ".bss". I didn’t know of this optimization till recently, though it’s been present for many years.