Плохая связь `char *array[size]` и `extern char **array`?

Во-первых, посмотрите на этот пример (я придумал его для примера, это не настоящая программа):

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!

6
задан Shahbaz 29 May 2012 в 16:37
поделиться