1

I've been told that when we write int a[100] = {1};, the elements after 1 will be initialized to 0. But I didn't find out how this is done. (And is this true?)

I've tried the code below to roughly find out the time cost:

#define M 500000

clock_t begin = clock();

int main(){
    /*-1-*/   //int a[M] = {1};
    /*-2-*/   //int a[M]; memset(a, 0, sizeof(int) * M);
    /*-3-*/   //int a[M]; for(int i = 0; i < M; i++)   a[i] = 0;
    
    clock_t end = clock();
    cout<<(double) (end - begin) / CLOCKS_PER_SEC<<endl;
    return 0;
} 

Where -1- to -3- is the 3 cases tested. Each time I use one of them. On my computer, the average time of the first 2 cases is 0.04, and the 3rd case costs 0.08 (Each tested for 10 times). So I guess the initialization is done like memset?

But I'm still confused whether these two are the same. If so, who is doing this?

Please excuse me for my poor English.


Thanks for the comments! And I've read the references and the linked questions. I've make it clear that the compiler does make the remainder elements to 0, but how is this done in lower level... maybe assembly? I'm sorry I didn't find references about that.

I'm new to stackoverflow, should I just edit my question like this?


Update:

Thanks a lot! I think I'm clear now.

The standard says when I int a[100] = {1};, the rest will be left 0. So my compiler will use some method to implement this, and different compiler may do this in different way. (Thank @eerorika to let me understand this!)

And thank @john for the site godbolt.org where I can read the assembly produced easily. Here I find out in x86-64 gcc 10.2(although in C but not C++), int a[100] = {1}; behaves like:

        leaq    -400(%rbp), %rdx
        movl    $0, %eax
        movl    $50, %ecx
        movq    %rdx, %rdi
        rep stosq
        movl    $1, -400(%rbp)
        movl    $0, %eax

It use stosq to save 0's every quad-words for 50 times, which equals to 2 int to initialize the array.

And thank @largest_prime_is_463035818 to let me know my mistake in measuring time.

Thank all you for making me clear!

XuanInsr
  • 119
  • 6
  • 2
    https://en.cppreference.com/w/c/language/array_initialization – 463035818_is_not_an_ai Dec 09 '20 at 06:06
  • 2
    you measured the time without optimizations turned on. Measuring times without optimiztations is close to meaningless, because in a release build runtimes can be completely different – 463035818_is_not_an_ai Dec 09 '20 at 06:07
  • 1
    `who is doing this` Not sure what you mean by that. Anyway, it's the same "*who*" that makes sure `int n = 123;` or `char s[] = "abc";` get initialized as required. – dxiv Dec 09 '20 at 06:08
  • 1
    https://stackoverflow.com/questions/1065774/initialization-of-all-elements-of-an-array-to-one-default-value-in-c – Martheen Dec 09 '20 at 06:09
  • 1
    Everything your program does is done in assembly. You might find this site helpful https://godbolt.org/, it will show you what assembly different compilers produce from your code. – john Dec 09 '20 at 06:36
  • Thanks for largest_prime_is_463035818 and Martheen I've know that the compiler does make the elements to 0; And thanks to dxiv , I didn't make my question clear. I've edit my question to make myself clear. – XuanInsr Dec 09 '20 at 06:37

2 Answers2

2

There is an answer to your question, but the C++ standard C++ latest draft - 9.4.2 Initializers - Aggregates (dcl.init.aggr) defines the elements explicitly initialized, and elements not explicitly initialized are copy initialized from an empty initializer list decl.init.aggr/5.2

I've been told that when we write int a[100] = {1};, the elements after 1 will be initialized to 0.

You were told correctly. With int a[100] = {1};, a[0] is explicitly initialized from the initializer list, the remaining a[1-99] are copy-initialized from an empty list to 0.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • 2
    Er, the C++ standard says what happens right in the section you linked. [`[dcl.init.aggr]/5`](http://eel.is/c++draft/dcl.init.aggr#5): "For a non-union aggregate [which applies here], each element that is not explicitly initialized [i.e. the elements after the first one, which aren't mentioned in the list] is initialized as follows: If the element has a default member initializer [they don't]...; Otherwise, if the element is not a reference [they aren't], the element is copy-initialized from an empty initializer list [in this case, each `int element = {};` initializes `element` to `0`]." – HTNW Dec 09 '20 at 07:50
  • 1
    Yes, I read through that but was not convinced the copy-initialized would apply to a plain-old array. If it does, then that satisfies all point in the standard. I'll update - thank you. – David C. Rankin Dec 09 '20 at 07:52
1

But I didn't find out how this is done.

It is done by the compiler.

And is this true?

Yes, this is true.

but how is this done in lower level

It can be done in any way that the compiler designer had chosen.

If you are interested on what your compiler did, you can read the assembly that it produced.

I'm sorry I didn't find references about that.

There is no reference for that.

eerorika
  • 232,697
  • 12
  • 197
  • 326