1

Foreword - I seem to have a solution, but I am not sure it is correct because I do not understand how compiler handles it. And yes, I performed research, which did not convince me in reliable and correct result.

This is C (not CPP). Language option is -std=gnu99.

Problem: I have structure

struct my_structure { uint8_t my_array[256]; };

Then I define the memory location for the struct

struct my_structure my_structure_data { .my_array[0 ... 255] = 0 };

This method is expected to have all 256 locations of my_array of the my_structure_data to be filled with zeroes. The format of the instruction is unambiguous and I would be very surprised if it would result in something else.

GCC gives me warning (pedantic mode is set deliberately)

warning: ISO C forbids specifying range of elements to initialize [-Wpedantic]

Ok, I am searching for the replacement, and found that

struct my_structure my_structure_data { .my_array = {0} };

gives no warnings. .my_array[256] = {0}; gives an error, saying I am trying to initialize 257th element of the array and it does not exist (logically).

So the question(s)

  • what .my_array = {0}; actually does, the confusing for me is no index part of the array. How does compiler know that {0} is not a value for first element, but value for all elements in the array?
  • how portable is it? What standard version defines that behavior?
  • can you propose better/more reliable way for array initialization in the static structure footprint?

Selected solution

I have chosen to explicitly initialize array. Should be problematic if array size would be bigger

struct my_structure my_structure_data { .my_array = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

Whatever assumption there're, whatever platform I compile for, I now sure all elements are 0.

7
  • "The format of the instruction is unambiguous" That would require that [0 ... 255] was a thing in C. There is no .. or ... operator in C. You would need to extent the language for that. Commented Sep 11, 2023 at 9:57
  • 2
    "How does compiler know that {0} is not a value for first element" That is not related to struct initialization. That is just how arrays are initialized in C. Any elements that do not have a value in the initializer list are automatically initialized to 0. That means, .my_array = {0} will set all elements to 0 but .my_array = {123} will not set all elements to 123. Instead only first element is 123 and all remaining will hold value 0. Commented Sep 11, 2023 at 9:59
  • @Anonymous, "Initialize all elements in array to same value within the struct" --> There is no standard way to do this, other than 0. Commented Sep 11, 2023 at 10:01
  • struct my_structure my_structure_data { .my_array = {0}; } is not valid initialization statement in C, because it is missing =. Either you are using some compiler extensions or some other language compiler (possibly C++?). If this is not the case, then please check that code you have posted is correct, and edit your question if it's not. Commented Sep 11, 2023 at 10:01
  • @Gerhardh I am not convinced. Read somewhere else this assumption works in CPP and not C. I always assumed, since turbo-c (on X86), that when you create array without initialization, all its elements are zeroes. Now I program another platform and must ensure all the elements are initialized with zero. If it is not possible to do during static data declaration (the hard data appearing in the executable file), I will use memset. Commented Sep 11, 2023 at 10:03

2 Answers 2

1

what .my_array = {0}; actually does

It actually just sets the first item in the array to zero. But there is a rule in C saying that if at least one member of a struct/array is initialized explicitly, the rest of them should be initialized too "as if they have static storage duration", which is another way of saying that they will all get set to zero.

Therefore .my_array = {1}; would set the first array item to 1 and the rest of them to zero.


how portable is it?

  • The = {0} part is extremely portable, this has been well-defined and standardized in all versions of C.
  • The .my_array part is called designated initializers and is present in all C language revisions since C99. It does not work in C90.
  • The [0 ... 255] is non-standard GNU C and non-portable.

can you propose better/more reliable way

Using the = {0} to set all items to zero/null is idiomatic C. If you want to initialize them to non-zero values, then that's another story.

Check out Initializing entire 2D array with one value and initializing an array of ints for details.

Sign up to request clarification or add additional context in comments.

Comments

1

For starters there are typos

struct my_structure my_structure_data { .my_array = {0}; }
                                    ^^^               ^^^ 

There must be

struct my_structure my_structure_data = { .my_array = {0} };

As for your question

what .my_array = {0}; actually does, the confusing for me is no index part of the array. How does compiler know that {0} is not a value for first element, but value for all elements in the array?

{0} is indeed a value for the first element of the array. All other elements are implicitly initialized by zeroes.

This initialization

struct my_structure my_structure_data = { .my_array = {0} };

is equivalent to

struct my_structure my_structure_data = { .my_array[0] = {0} };

or is the same as

struct my_structure my_structure_data = { .my_array[0] = 0 };

From the C Standard (6.7.9 Initialization)

19 The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject;151) all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.

and

10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:

— if it has pointer type, it is initialized to a null pointer;

— if it has arithmetic type, it is initialized to (positive or unsigned) zero;

— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

— if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

1 Comment

thanks, made some typos in the post... corrected, hopefully did not introduce more of them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.