6

まず、この例を見てください (これは例のために作成したもので、実際のプログラムではありません):

なんでも.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

4

1 に答える 1