I have searched for this online but have found conflicting information.
Please do not read random blogs or such, they usually have bad information. On Stack Overflow wrong information tends to be downvoted or at least would usually have comments pointing out the inaccuracies and fallacies.
In the above program, both arr and x are locally declared within the main function. I thought that this would mean that they would both be allocated space on the function stack.
The C standard does not specify how memory for variablesobjects should be allocated. It only specifies that objects have storage durations, which define the lifetime of the variableobject
- static, which will have lifetime from the beginning of the program until the very end
- automatic, which will have the lifetime of the innermost block
{ ... } which contains the declaration (or compound literal), until the end of the block - thread-local, which will have the lifetime of a thread
- allocated objects, which will be alive from
malloc/calloc/realloc/aligned_alloc until corresponding free/realloc.
In addition to that, the C standard specifies that during its lifetime, an object will
- have memory reserved for it
- and have a constant address (which you can observe by using the
& operator)
Now, in addition to that, there is the so-called as-if rule which says that a compiler can produce any program code for as long as the external behaviour of the program is the same, external behaviour meaning input, output, access to volatile objects and so on.
The variables in your program have automatic storage duration, which means every time you enter the main function you will have new objects with new lifetime until the end of the main function. Usually this would mean that they would be stored on the stack, because it will nicely handle the allocations and deallocations with minimal overhead. But your program has the same external behaviour as
#include <stdio.h> int main(void) { printf("Hello World!"); }
It means that the compiler can completely eliminate these two variables and not reserve any space for it.
Now, if you print address of the variables:
#include <stdio.h> int main(void) { int arr[4] = {1,2,3,4}; int x = 10; printf("Hello World! %p, %p\n", (void *)arr, (void *)&x); }
because the variables have their addresses taken and used for output, C cannot optimize them out. Are they on stack now? Well, C standard does not say. They need to have lifetime from at least beginning of main until the end - but the C compiler can decide to not use the stack for them, as the external behaviour of that program would be the same as
#include <stdio.h> static int arr[4] = {1,2,3,4}; static int x = 10; int main(void) { printf("Hello World! %p, %p\n", (void *)arr, (void *)&x); }
which would put these variables in the static data segment; of course the addresses would be different but again C does not give any guarantees about where the particular objects are located in memory, just that they will have addresses.
{1,2,3,4}will be stored in the program image in the data section. At runtime, if your program even does create the array variable (since as someone else said, the optimizer can remove anything that has no effect) it will create space for the array on the stack then copy the initializer into it. Or if using the optimizer it might drop the initializer and replace it with inline register set instructions.