Can't figure out the reason for the output? [duplicate] - c

This question already has answers here:
Why is this array having all remaining values initialized to zero?
(4 answers)
Does a string literal count as a partial initializer and zero-initialize?
(3 answers)
Closed 4 years ago.
//Language C
int main()
{
int a[5]={0};
for(int i=0 ; i < 4 ; i++ )
printf("%d",a[i]);
}
}
The output of the following was 1000 in gcc. But I thought it should print 1 and rest garbage values as I have not assigned values to other array locations.
If compiler version is not taken in account, is my thinking right? Or I am missing something.

The C standard (citing the latest C11 draft N1570 here) explains this quite well.
§6.7.9 Initialization, p21:
If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.
(emphasis mine)
so, every element except a[0] in your code is initialized implicitly. Now let's look what that means:
§6.7.9 Initialization, p10:
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;
(again, emphasis mine)
so, a[1] to a[4] are initialized to 0 -- type int is an arithmetic type.

Related

zeroing memory area of a structure in c [duplicate]

This question already has answers here:
what is the difference between struct {0} and memset 0 [duplicate]
(2 answers)
memset() or value initialization to zero out a struct?
(8 answers)
Closed 4 years ago.
I have following structure and i want to initialize it to zero.
struct example {
int a;
int b;
char c;
};
struct example mystruct;
I can memset mystruct to zero in following ways:
memset(&mystruct, 0, sizeof(mystruct));
or
mystruct = (struct example) {0};
Is the second way is equal to the first one?
Note that i want to initialize mystruct variable to zero not only at variable definition, maybe for reusing it.
Well, in your case, they will be equivalent (disregarding the padding bytes).
Quoting C11, chapter §6.7.9/ P21, (emphasis mine)
If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.
and, regarding the initialization of static storage duration objects, P10 (again emphasis mine)
[...] 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;
For sake of completeness, as mentioned in the below comment by Serge Ballesta:
all remaining members will be initialized implicitly the same as objects that have static storage duration. And the standard does not mandate anything for the padding bits of the top level object
which indicates, the assignment will differ from the memset() call in case of the first object / member, for the padding values.
No, they are not equal.
The first is more low-level, it will set all bits of the value to 0, including those that are not part of any member (padding).
The latter is only guaranteed to set the actual members to zero, so it might be faster since it has the opportunity to touch less memory.

Unused indices of a global initialized array? [duplicate]

This question already has answers here:
What happens to fields not named by a designated initializer?
(1 answer)
Why is this array having all remaining values initialized to zero?
(4 answers)
Closed 5 years ago.
I have a struct array. Only a few index locations need to be initialized. Is there a compiler attribute that ensures that the uninitialized combinations are init'd to 0 ?
For example:
If I have a statically init'd struct array as below, how can I ensure that the remaining 3 elements in that array (which are not explicitly pre-init'd) are zero'd out ?
typedef struct foo_s {
int a;
int b;
} foo_t;
foo_t foo_array[4] = {
{ .a = 1, .b = 2 },
};
Thanks,
The behavior you want is already part of standard C. There are no "half-initialized" variables; if you only initialize part of something, then all remaining elements will be zero-initialized.
Besides, you say (in your title) that this array is global. That means it has static storage duration, so it will be zero-initialized even if you don't provide any initializer at all.
Quoting C99 on aggregate initializers:
6.7.8/19:
[...] all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.
6.7.8/21:
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
6.7.8/10:
If an object that has static 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;
if it is a union, the first named member is initialized (recursively) according to these rules.

structure on the stack - fields initialized? [duplicate]

This question already has an answer here:
C struct automatic initialization values, array initializations
(1 answer)
Closed 4 years ago.
Consider the following code:
void func()
{
int p;
...
if (p > MAX) {
struct my_struct s;
...
/* here we access the contents 's' as '&s' */
}
}
In this snippet s is on the stack. Is it guaranteed that the compiler initializes all structure fields to zero?
If a variable (struct or otherwise) is declared local to a function or a containing scope (i.e. has automatic storage duration), it is not initialized in any way. You need to explicitly set the fields in the struct.
If you initialize at least one field of a struct but not all, then the remaining fields will be initialized the same as file scope variables (i.e. variables with static storage duration), which means NULL for pointer types and 0 for numeric types.
From section 6.7.9 of the C standard:
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;
...
21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in
a string literal used to initialize an array of known size than there
are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage
duration.
No, it's quite the opposite.
Since s is an automatic storage local scoped (i.e., block scoped) variable, unless initialized explicitly, the contents are indeterminate.
Quoting C11, chapter §6.7.9
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. [...].
However, if you want to zero-initialize the variable for an(y) aggregate type, you can simply use an initialization statement like
aggregate-type variable = {0};
which uses the following property from paragraph 21 of the same chapter, (emphasis mine)
If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.
No, they won't be initialized at all. The structure values will end up with whatever garbage is on the stack where the structure is placed.

Value of uninitialized elements in array of C language

I have an array of 3 elements. But I only want to initialize 2 of them.
I let the third element blank.
unsigned char array[3] = {1,2,};
int main(){
printf("%d",array[2]);
return 0;
}
The print result is 0. I tested it on IAR, and some online compiler.
Is there any C rule for the value of third element?
Is there any compiler filling the third element by 0xFF ? (Especially cross compiler)
Yes, the C standard does define what happens in this case. So no, there should be no C standard compliant compiler that intialises with 0xFF in this case.
Section 6.7.9 of the standard says:
Initialisation
...
10 ...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;
...
21 If there are fewer initializers in a brace-enclosed list than there
are elements or members of an aggregate, or fewer characters in a
string literal used to initialize an array of known size than there
are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage
duration.
From this post, it appears that that syntax will initialize all elements after the comma to zero. Moreover; all uninitialized data in the data segment of the program (in other words all uninitialized global variables) are automatically set to zero, so if you are looking for undefined behavior in this program, there isn't any; it will always be 0.
This can be achieved with gcc extension as below
unsigned char array[10] = {1,2,[2 ... 9] = 0xFF};

How all the elements of array initialize to zero and first element to 1 in c [duplicate]

This question already has answers here:
how does array[100] = {0} set the entire array to 0?
(4 answers)
Closed 7 years ago.
Here is the program the array automatically initialize to zero and first element initialize to 1 when declare as int arr[10]={1}
#include<stdio.h>
int main()
{
int i;
int arr[10]={1};
for(i=0;i<10;i++)
{
printf("\n%d",arr[i]);
}
return 0;
}
how array elements are initialized to zero expect the first element?
The array elements are initialized based on the initialization rule for aggregate type with initialization lists, as specified in C standard.
It mentions, if there are less number of initializers supplied in the brace-enclosed list than that of the number of element in the aggregate type, the remaining elements in the aggregate type will be initialized with the value as if they have static storage duration, i.e., a value of 0.
To quote C11, chapter §6.7.9, Initialization (emphasis mine)
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
and regarding the initialization of variables having static storage duration,
[..] If an object that has static or thread storage duration is not initialized
explicitly, then:
[...]
if it has arithmetic type, it is initialized to (positive or unsigned) zero;
[...]
So, very rightly, in your case
int arr[10]={1};
arr[0] is having a value 1, arr[1] to arr[9] all are set to 0.

Resources