Issue
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.
Solution
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.
Answered By - Lundin Answer Checked By - Terry (WPSolving Volunteer)