I was testing out scopes and visibility when I came across this situation I can't find an explanation for :
I have two .c files :
F1.c
#include <stdio.h>
void Modify();
int i;
int j;
int main()
{
i=1;
printf("i (main 1) = %d\n", i);
Modify();
printf("i (main 2) = %d\n", i);
return 0;
}
and F2.c
#include <stdio.h>
extern char i [10];
extern int j;
void Modify()
{
j=0;
i[0]='a';
i[1]= 'b';
i[4]= 'e';
printf("i (Modify) = %c\n", i[0]);
printf("j (Modify) = %d\n", j);
}
When I compile and link them to create the executable that I Launch, here is the result :
i (main 1) = 1
i (Modify) = a
j (Modify) = 0
i (main 2) = 25185
What is happening? Does i changes types? Does giving an array with a size overpowers the declaration of i in F1.c?
Thanks!
This is against the rules of C. External globals need to have consistent declarations. (That's why we use headers to maintain the consistency.) You've given your toolset permission to make a mess of things.
That being said, what's happening in your case is that the objects are simply overlaid (probably sufficient storage is being allocated for both int
, and char[10]
, sort of like if there was a union
there. If only 4 bytes are allocated (just for the int
, not the array) then the i[4]
access will overwrite something or less likely cause a segfault.).
25185
is 0x6261
, which assuming a little endian architecture corresponds to {0x61, 0x62, 0x00, 0x00}
, i.e;, {'a', 'b', 0, 0 }
. The 'e'
isn't included in that number because your architecture's int
s are 4 bytes large and the 'e'
was put at the 5th byte.
Again, you're in the realm of UB, so none of this is guaranteed behavior.