Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the difference between int a[5] = {0} and int a[5]={1} (Missing Feature) [closed]

When we initialize an array like this int a[5] = {0}, the compiler makes all 5 elements 0. That is really good, compact-initialization and useful feature.

But I wonder why the compiler doesn't initialize int a[5]={1} similarly? Why does it not make all 5 elements 1? Why the Standard doesn't mandate it? Would it not been an awesome feature? Isn't it missing?

Also, if the number of elements in the initializer is less than the size of the array, then the compile could initialize the remaining elements with the last element in the initializer. Means, int a[5]={1,2,3} is equivalent to int a[5]={1,2,3,3,3}. And similarly, int a[10]={1,2,3,0} is equivalent to int a[10]={1,2,3,0,0,0,0,0,0,0};.

Would it all not be an awesome feature if the Standard mandates it? Or is there any good reasons for this missing feature?


And there is something called designated initializer in C99, which is used like:

Designated initializers can be combined with regular initializers, as in the following example:

int a[10] = {2, 4, [8]=9, 10}

In this example, a[0] is initialized to 2, a1 is initialized to 4, a[2] to a[7] are initialized to 0, and a[9] is initialized to 10.

Quite interesting. But even this feature is not in C++.

like image 402
Nawaz Avatar asked Dec 05 '22 23:12

Nawaz


2 Answers

Why does it not make all 5 elements 1?

Because you're misunderstanding what {} means. (Actually, in C++ the better way to do this is {} rather than {0}). The syntax {0} does not mean that you want all elements in the aggregate set to zero. Rather, it says that you want an aggregate with the first element zero assigned to the indicated variable (which can be either an array or a class type in C++). Because the aggregate usually has more fields than that one value zero, the remaining elements in the aggregate are default constructed. The default value of a builtin or POD type is to set all of the fields to zero, so you've effectively set the entire aggregate to zero.

As for why specifically, consider the following. According to the current standard, none of the assertions below will fail:

struct abc
{
    char field1;
    int field2;
    char field3;
};

int main()
{
    abc example = {'a', static_cast<int>('b')};
    //All three asserts pass
    assert(example.field1 == 'a');
    assert(example.field2 == static_cast<int>('b'));
    assert(example.field3 == '\0');

    int example2[3] = {static_cast<int>('a'), 42};
    assert(example2[0] == static_cast<int>('a'));
    assert(example2[1] == 42);
    assert(example2[2] == 0);
}

What would you expect the value of field3 to be in your proposed standard change? Even if you define it as the last element in the aggregate initializer as you've shown above, that's going to break compatibility with existing code which assumes the rest of the elements are default constructed.


EDIT: Just realized that your question is asked in terms of arrays - but the answer is the same with either structures or arrays, so it really doesn't matter.

EDIT2: To make this more in keeping with the standard, references to class/structure have been replaced with "aggregate" below, which covers the structures and arrays cases.

like image 60
Billy ONeal Avatar answered Dec 09 '22 15:12

Billy ONeal


Yes, they could have done that, but they didn't, and it's far too late now to change such behavior. The decisions behind C and C++ were made with thought given to performance and minimalism at almost every step, so I imagine that, if nothing else, comes into play here as well.

Such a feature just doesn't strike me as all that awesome. It's a very simple piece of syntactic sugar, and I rarely find the need to initialize an array like that to anything other than 0 anyway.

like image 37
MikeP Avatar answered Dec 09 '22 14:12

MikeP