First, see this example (I made this up for the sake of example, it's 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 make this program using:
gcc -o test main.c whatever.c -Wall -g
I don't get any errors or warnings. However, when I run the program, I see that in fill
, names
is actually NULL
. If in whatever.c
I change
extern char **names;
to
extern char *names[];
then everything is fine.
Can anyone explain why this happens? If gcc couldn't link extern char **names;
with the one in main.c
, shouldn't it have given me an error? If it could link them, how come names
ends up being NULL
in whatever.c
?
Also, how does extern char **names;
differ from extern char *names[];
?
I am using gcc version 4.5.1 under Linux.
Update
To further investigate this, 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 with gdb
, I can see that names
has a value. If I cast that value to char *
and print it, it gives me "1"
. (Note that, it's not *names
that is "1"
, but (char *)names
)
Basically, what it means is that gcc has somehow managed to link extern char **names;
in whatever.c
with names[0]
in main.c
!