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
!