On most OSes, static or global arrays are initialized to zero by putting them in the bss
(block storage space) section of an executable. When an executable is loaded by the OS, zeroed memory is mapped to the BSS address (with enough pages to cover the bss size the executable stores in it's ELF header, or whatever executable format the OS uses.)
If you have a non-zero initializer for even one of the values in the array, though, then the entire thing has to go in the data
section. (or rodata
, if it's a const
array.) If you have a big array that starts of mostly-zeroed but with a couple non-zero elements, you can save space and load-time by writing it as all-zero, with an initializer. (C doesn't have any provisions for constructors for globals, but C++ does).
Array local variables in functions/methods (i.e. allocated on the stack) need to be written every time they're initialized. Compilers typically generate an inlined memset (either a loop or fully unrolled), or even a call to memset
.
Local-variable array initialization costs linear time (and cache pollution). Global / static array initialization to all zero is free (since the kernel can efficiently obtain zeroed pages of memory for the BSS). Global / static arrays with even a single non-zero initializer cost linear process-startup time (if you actually read the whole array) in I/O to read in the data from disk (even the zero portions).