4

Disclaimer: I might have misunderstood how arrays are created, allocated and initialised. If so, please try to read between the lines.

If I create an array by doing

int array[15] = {0};

All elements of array the compiler will initialise the elements to 0. How is this done by the compiler? Does the compiler insert a loop that iterates the allocated memory and sets each element to zero? Does size impact performance? I.e. does it takes longer time to initialise an array of double size (30)? How much longer? Double? Logarithmic? Power of 2?

Only asking out of curiosity.

T'n'E
  • 598
  • 5
  • 17
  • 1
    Why are you asking on here when it's easier to compile that and just look at the assembler? – Martin James Aug 11 '15 at 12:31
  • ***[Here](https://en.wikipedia.org/wiki/Initialization_%28programming%29)*** is a little blub on it in Wiki. – ryyker Aug 11 '15 at 12:32
  • You have 2 ways to go here: measure time of `n` allocations, or check the sources of your compiler. – Theolodis Aug 11 '15 at 12:32
  • @MartinJames: Because I don't understand assembly code. :) Plus I don't know how to actually view it. – T'n'E Aug 11 '15 at 12:38
  • @Theolodis: There is no usual/standard/preferred way of doing it that most compilers do? – T'n'E Aug 11 '15 at 12:39
  • related question: [initialize array to 0 in C](http://stackoverflow.com/questions/2589749/initialize-array-to-0-in-c) – luoluo Aug 11 '15 at 12:41
  • 1
    You shouldn't use `{0}`. You should use `{}`. http://stackoverflow.com/q/14797810/560648 – Lightness Races in Orbit Aug 11 '15 at 12:50
  • 2
    @Lightness Races in Orbit: This question is about C (however GNU C allows `{}`). – cremno Aug 11 '15 at 12:59
  • @cremno: Yes, I am aware of that. Did you read the question and answer I linked to? The rationale still applies. – Lightness Races in Orbit Aug 11 '15 at 13:00
  • 2
    @LightnessRacesinOrbit - If we are talking about _standard_ C99 C, `{0}` is valid. The link you provided ( and `{ }` ) is specific to c++. – ryyker Aug 11 '15 at 13:01
  • 1
    @ryyker: I never said it was not "valid" in C, and it does not matter that the link is to a C++ question. Neither of you are reading properly. – Lightness Races in Orbit Aug 11 '15 at 13:03
  • 3
    @LightnessRacesinOrbit: My issue with your comment is your comment and not the linked answer. You shouldn't use `{}` in C because it's non-standard. You could've just recommended reading the answer. – cremno Aug 11 '15 at 13:07
  • After your edit, `int array[15];` leaves the array uninitialized, provided that the array is not global. The `={0}` *is* required to initialize all the elements in the array to zero. – Spikatrix Aug 11 '15 at 13:17
  • I'm curious about both local and global variables. In the example it is (now) local. – T'n'E Aug 11 '15 at 13:25

6 Answers6

5

I assume, you are talking about global variables/arrays.

Actually, it is not compiler task (if we are talking about modern OSes). Compiler just marks this object as zero-initialized.

Then, linker puts this object in section, that should be initialized with zeros. In ELF this section is named .bss. Usually, this section has no data (because there are only zeroes), but it has size.

And then, when loader loads your program into memory, it knows, that it should zero out memory that belongs to .bss section.

If we are talking about stack-based (local) variables, then compiler just calls memset()

werewindle
  • 3,009
  • 17
  • 27
  • Pretty sure he is talking about local variables, otherwise the `={0}` is redundant. – Lightness Races in Orbit Aug 11 '15 at 12:48
  • I was curious about both, although I didn't state it. `={0}` was just for clarity. – T'n'E Aug 11 '15 at 12:51
  • 2
    @LightnessRacesinOrbit - Actually, I did read it, and understood it well enough. Was intrigued, so tried it in my C99 compiler (with both global and local scope). Without an explicit initializer, i.e.: `{ }` , compile error states Illegal expression. Very nice answer by the way, but I think with the exception of gcc (with several non-standard extensions),this will not work. (excluding C++ of course) – ryyker Aug 11 '15 at 13:08
  • @ryyker: Well, granted, you need to use GNU C like 99% of the C world. The point is that saying `{0}` initialises all elements to zero implies that the `0` is responsible. It's not. `{1}` initialises the first element to 1 and default-initialises the rest (i.e. `0`). So it's a bad practice. It's a shame that C89 and C99 require the dummy `0` to hack around bad syntax rules, I'll grant you. – Lightness Races in Orbit Aug 11 '15 at 13:10
  • 1
    @LightnessRacesinOrbit - Lol, well, there is that! I happen to be constrained to my minority, but very compliant compiler. I do use gcc by the way, but only for proof of concept stuff not needing to be portable. And also by the way, as usual, you make very compelling (and enjoyable) arguments. – ryyker Aug 11 '15 at 13:14
  • @ryyker: Meanwhile, you wouldn't catch me writing C. :) – Lightness Races in Orbit Aug 11 '15 at 13:18
  • @LightnessRacesinOrbit - likewise, me with C++. I'm still learning C! – ryyker Aug 11 '15 at 13:20
2

In C the compiler usually uses standard C function memset for locally defined arrays.

P.S. For example in IBM mainframe if I am not mistaken function memset is implemented with two mashine instructions something like MVI and MVCL and can be inlined. Truly speaking I do not already remember. If you are interesting you should look through the object code generated by the IBM XL C++ compiler.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

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).

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
2

Standard only requires that the array shall be initialized before it can be used. It also says that object with static storage duration will be initialized to 0 if not explicitely initialized whereas object with dynamic storage duration will be initialized to undeterminate values if not explicitely initialized.

Common rules are:

  • object with static storage duration are initialized at build time (compile + link)
  • object with dynamic storage duration can only be initialized at run time. In your example, it would look like a memset: the time will be broadly linear with the global size.
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

compiler will set first array element to the value you've provided (0) and all others will be set to zero because it is a default value for omitted array elements.

Keerthi Mukku
  • 113
  • 1
  • 1
  • 9
0

All elements of array the compiler will initialise the elements to 0. How is this done by the compiler?

By writing 0s into the related memory in an implementation defined manner.

alk
  • 69,737
  • 10
  • 105
  • 255