まず、この例を見てください (これは例のために作成したもので、実際のプログラムではありません):
なんでも.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;
}
なんでも.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
エラーや警告は表示されません。しかし、プログラムを実行すると、 inが実際にはfillであることがわかります。私が変わるならnamesNULLwhatever.c
extern char **names;
に
extern char *names[];
その後、すべてが順調です。
なぜこれが起こるのか誰か説明できますか?gcc がextern char **names;のものとリンクできなかった場合main.c、エラーが発生するはずではありませんか? それらをリンクできるとしたら、なぜにいるのnamesでしょうか?NULLwhatever.c
また、 は とどうextern char **names;違うのextern char *names[];ですか?
Linux で gcc バージョン 4.5.1 を使用しています。
アップデート
これをさらに調査するために、namesinの定義を次のように変更しますmain.c。
char *names[10] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
( を保持) と を使用するとextern char **names;、に値があることがわかります。その値をキャストして出力すると、. (ただし、そうではないことに注意してください)whatever.cgdbnameschar *"1"*names"1"(char *)names
基本的に、これが意味することは、gcc が何とか in ! とリンクできextern char **names;たことwhatever.cですnames[0]。main.c