Во-первых, посмотрите на этот пример (я придумал его для примера, это не настоящая программа):
what.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;
}
what.c
#include "whatever.h"
extern char **names;
void fill(void)
{
int i;
for (i = 0; i < 10; ++i)
names[i] = "some name";
}
Когда я создаю эту программу, используя:
gcc -o test main.c whatever.c -Wall -g
Я не получаю никаких ошибок или предупреждений. Однако, когда я запускаю программу, я вижу, что в fill
, names
на самом деле NULL
. Если в what.c
поменять
extern char **names;
на
extern char *names[];
то все нормально.
Кто-нибудь может объяснить, почему это происходит? Если gcc не смог связать extern char **names;
с именем в main.c
, разве это не должно было вызвать ошибку? Если бы это могло связать их, то почему имена
оказались NULL
в чем бы то ни было.с
?
Кроме того, чем extern char **names;
отличается от extern char *names[];
?
Я использую gcc версии 4.5.1 под Linux.
Для дальнейшего исследования я изменил определение имен
в main.c
на:
char *names[10] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
(сохранив extern char **names;
в what.c
) и с gdb
я вижу, что names
имеет значение. Если я приведу это значение к char *
и напечатаю его, оно даст мне "1"
. (Обратите внимание, что "1"
- это не *names
, а (char *)names
)
По сути, это означает, что gcc каким-то образом удалось связать extern char **names;
в what.c
с именами[0]
в main.c
!