First, look at this example (I did this for an example, this is not a real program):
whatever.h
#ifndef WHATEVER_H #define WHATEVER_H void fill(void); #endif
main.c
#include <stdio.h> #include "whatever.h" char *names[10] = {NULL}; int main() { int i; fill(); for (i = 0; i < 10; ++i) printf("%s\n", names[i]); return 0; }
whatever.c
#include "whatever.h" extern char **names; void fill(void) { int i; for (i = 0; i < 10; ++i) names[i] = "some name"; }
When I do this program using:
gcc -o test main.c whatever.c -Wall -g
I do not receive any errors or warnings. However, when I run the program, I see that in fill , names are actually NULL . If in whatever.c I change
extern char **names;
to
extern char *names[];
then everything will be fine.
Can anyone explain why this is happening? If gcc could not bind extern char **names; with the one that was in main.c , shouldn't it give me an error? If he could bind them, how did it happen that names would be NULL in whatever.c ?
Also, like extern char **names; different from extern char *names[]; ?
I am using gcc version 4.5.1 under Linux.
Update
To continue the research, I change the definition of names in main.c to:
char *names[10] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
(keeping extern char **names; in whatever.c ) and gdb , I see that names matters. If I pass this value to char * and print it, it will give me "1" . (Note that these are not *names , that is, "1" , but (char *)names )
Basically, this means that gcc somehow managed to bind extern char **names; in whatever.c with names[0] in main.c !