Everywhere I look there are people who argue vociferously that uninitialised variables are bad and I certainly agree and understand why - however; my question is, are there occasions when you would not want to do this?
For example, take the code:
char arrBuffer[1024] = { '\0' };
Does NULLing the entire array create a performance impact over using the array without initialising it?
The process of assigning values to the array elements is called array initialization. Once an array is declared, its elements must be initialized before they can be used in the program. If they are not properly initialized the program produces unexpected results.
Initialize Arrays in C/C++ c. The array will be initialized to 0 if we provide the empty initializer list or just specify 0 in the initializer list.
To initialize an array of arrays, you can use new keyword with the size specified for the number of arrays inside the outer array. int[][] numbers = new int[3][]; specifies that numbers is an array of arrays that store integers.
I assume a stack initialization because static arrays are auto-initialized.
G++ output
char whatever[2567] = {'\0'};
8048530: 8d 95 f5 f5 ff ff lea -0xa0b(%ebp),%edx
8048536: b8 07 0a 00 00 mov $0xa07,%eax
804853b: 89 44 24 08 mov %eax,0x8(%esp)
804853f: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp)
8048546: 00
8048547: 89 14 24 mov %edx,(%esp)
804854a: e8 b9 fe ff ff call 8048408 <memset@plt>
So, you initialize with {'\0'} and a call to memset is done, so yes, you have a performance hit.
If the variable is a global or static, then its data is typically stored verbatim in the compiled executable. So, your char arrBuffer[1024]
will increase executable size by 1024 bytes. Initializing it will ensure the executable contains your data instead of the default 0's or whatever the compiler chooses. When the program starts, no processing is required to initialize the variables.
On the other hand, variables on the stack, such as non-static local function variables, are not stored in the executable the same way. Instead, on function entry the space is allocated on the stack and a memcpy places the data into the variable, thereby impacting performance.
The rule is that variables should be set before they're used.
You do not have to explicitly initialize them on creation if you know you will be setting them elsewhere before use.
For example, the following code is perfectly okay:
int main (void) {
int a[1000];
: :
for (int i =0; i < sizeof(a)/sizeof(*a); i++)
a[i] = i;
: :
// Now use a[whatever] here.
: :
return 0;
}
In that case, it's wasteful to initialize the array at the point of its creation.
As to whether there's a performance penalty, it depends partially on where your variable is defined and partially on the execution environment.
The C standard guarantees that variables defined with static storage duration (either at file level or as statics in a function) are first initialized to a bit pattern of all zeros, then set to their respective initialized values.
It does not mandate how that second step is done. A typical way is to just have the compiler itself create the initialized variable and place it in the executable so that it's initialized by virtue of the fact that the executable is loaded. This will have no performance impact (for initialization, obviously it will have some impact for program load).
Of course, an implementation may wish to save space in the executable and initialize those variables with code (before main is called). This will have a performance impact but it's likely to be minuscule.
As to those variables with automatic storage duration (local variables and such), they're never implicitly initialized unless you assign something to them, so there will also be a performance penalty for that. By "never implicitly initialized", I mean the code segment:
void x(void) {
int x[1000];
...
}
will result in x[] having indeterminate values. But since:
void x(void) {
int x[1000] = {0};
}
may simply result in a 1000-integer memcpy-type operation (more likely memset for that case), this will likely to be fast as well. You just need to keep in mind that the initialization will happen every time that function is called.
Measure!
#include <stdio.h>
#include <time.h>
int main(void) {
clock_t t0;
int k;
t0 = clock();
for (k=0; k<1000000; k++) {
int a[1000];
a[420] = 420;
}
printf("Without init: %f secs\n", (double)(clock() - t0) / CLOCKS_PER_SEC);
t0 = clock();
for (k=0; k<1000000; k++) {
int a[1000] = {0};
a[420] = 420;
}
printf(" With init: %f secs\n", (double)(clock() - t0) / CLOCKS_PER_SEC);
return 0;
}
$ gcc measure.c $ ./a.out Without init: 0.000000 secs With init: 0.280000 secs $ gcc -O2 measure.c $ ./a.out Without init: 0.000000 secs With init: 0.000000 secs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With