Redeclaration of global variable vs local variable
In C, the statement int a;
when made at file scope, is a declaration and a tentative definition. You can have as many tentative definitions as you want, as long as they all match each other.
If a definition (with an initializer) appears before the end of the translation unit, the variable will be initialized to that value. Having multiple initialization values is a compiler error.
If the end of the translation unit is reached, and no non-tentative definition was found, the variable will be zero initialized.
The above does not apply for local variables. Here a declaration also serves as a definition, and having more than one leads to an error.
The other reason I could think of is that un-initialized global variables are stored in the BSS (Block Structured Segment) where are the global variables that are initialized are stored in Data Segment.
I am guessing that there is some kind of a name space resolution and when there is a conflict the variable in the Data segment overrides the one in the Block Structured Segment.
if you were to declare
int a =5 int a = 10
in the global scope (both in the data segment) there would be conflict as expected.
You can't have two global variables with the same name in C program. C might allow multiple definitions in the same file scope through the tentative definition rule, but in any case all definitions will refer to the same variable.
Local Variable
In C, multiple local variables are not "merged" into one.
All the local variables with the same name will be referring to the different int-sized piece of memory.
#include<stdio.h>
int main()
{
int a;
int a = 10;
printf("a is %d \n",a);
return 0;
}
So when assigning the memory to the redeclaration of the same variable it gives an Error.
Global Variable
In C, multiple global variables are "merged" into one. So you have indeed just one global variable, declared multiple times. This goes back to a time when extern wasn't needed (or possibly didn't exist - not quite sure) in C.
In other words, all global variables with the same name will be converted to be one variable - so your
#include<stdio.h>
int a;
int a = 10;
int main()
{
printf("a is %d \n",a);
return 0;
}
will be referring to the same int-sized piece of memory.