`字符*阵列[大小]`和`的extern炭的坏联动** array`?(Bad linkage of

2019-06-24 22:43发布

首先,看看这个例子(我做了这件事,例如着想,这不是一个真正的程序):

whatever.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;
}

whatever.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

我没有得到任何错误或警告。 然而,当我运行程序时,我看到,在fillnames实际上是NULL 。 如果whatever.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。

更新

为了进一步调查这个,我改变的定义, namesmain.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

基本上,它的意思是,海湾合作委员会已总算链接extern char **names;whatever.cnames[0]main.c

Answer 1:

每当你使用不同的,不兼容的类型在不同的编译单元相同的变量(如你在这里做),你得到了一个未定义的行为。 这意味着它可能不会工作,你可能无法得到关于它的任何错误或警告消息。

为什么出现这种情况(以及为什么规范说这是不确定的),是由于道路大部分链接器工作。 大多数的连接器不理解什么类型; 他们只知道名字和记忆。 所以,只要连接器而言,变量仅仅是一个开始,在一些地址的内存块。 在您的(原始)程序main.c定义names为指的存储器足够大的块的开始到保持10个指针(大概40或80个字节,这取决于是否这是一个32位或64位系统),所有这一切都是空。 whaterver.c ,在另一方面,假设names指的存储器足够大的块为保持一个指针,并以10个指针的数组该指针指向。



文章来源: Bad linkage of `char *array[size]` and `extern char **array`?
标签: c gcc linkage