Let me try to explain the behavior of the code considering x86_64
architecture and gcc7.5x
compiler.
This answer and this answer to the questions provides the direction of stack growth on different architectures for x86
it is downward, meaning the stack will grow from high memory to low memory address (0xFF --> 0x00)
If we slightly modify your code to print the addresses and values of the variable during runtime as shown:
#include <stdio.h>
int main()
{
int m = 0;
int n = 0;
int x[n];
printf("Size of int: %d\n", sizeof(int));
printf("Address of\nm: %p\nn: %p\nx: %p\n", &m, &n, &x);
printf("Enter a value of m: ");
scanf("%d", &m);
printf("Enter a value of n: ");
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d", &x[i]);
printf("Addr: %p\n", &x[i]);
}
for(int j = 0; j < n; j++)
{
printf("x[%d]: %d\n", x[j]);
}
printf("m: %d n: %d\n", m, n);
}
After compiling and running the above code on x86
, we can notice that the addresses to the local variables get assigned in decreasing order as shown below for one of the code execution session:
Address of
m: 0x7ffdfb2b1704
n: 0x7ffdfb2b1700
x: 0x7ffdfb2b16f0
If you notice the difference in the address of n
and x
, they are 16-Bytes
apart, ideally they should have been 4-bytes
apart on stack.
But as int x[n]
is declared to be an array of 0 integers ideally it should occupy 4-bytes of memory, even though the underlying compiler and architecture mechanism is treating it as an array of 4 integers, which gets translated to
4 integers * sizof(int) = 16-bytes
Looking at further execution output of the code, we can see that the value of n
at address 0x7ffdfb2b1700
gets overwritten as the code executes further.
Note that the code will work properly for values of n < 5
, because for the value of n = 4
the loop will terminate at n = 3
in which case the value of n
will not get overwritten because of loop iteration as (n * sizeof(int)) ==> 3 * 4 = 12-bytes
:
Enter a value of m: 1
Enter a value of n: 10
1
Addr: 0x7ffdfb2b16f0
2
Addr: 0x7ffdfb2b16f4
3
Addr: 0x7ffdfb2b16f8
4
Addr: 0x7ffdfb2b16fc
5
Addr: 0x7ffdfb2b1700 <--- address of variable `n` getting overwritten with new value
x[1]: 0
x[2]: 1
x[3]: 2
x[4]: 3
x[5]: 4
m: 1 n: 5
And this is the reason why @DevSolar answered that this will result in an undefined behavior.
I hope I was able to provide some clarification.