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