Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 链接器无法区分函数和变量之间的差异?_C_Gcc_Linker - Fatal编程技术网

C 链接器无法区分函数和变量之间的差异?

C 链接器无法区分函数和变量之间的差异?,c,gcc,linker,C,Gcc,Linker,下面是我的代码: //Module 1 void sth() { } 当调用gcc时,链接器抛出一个错误: 找到对某事物的多种定义 但是这个链接是否愚蠢到无法区分函数和变量之间的区别?特别是在ELF中有一个符号表,Elf64\u Symbol中有一个“type”来区分函数和对象。链接器为什么不使用此信息?您为链接器提供了多个定义 符号sth在两个模块中定义,一个模块为int,另一个模块为void函数。如果同一符号出现在多个对象文件中,无论其类型如何,如果您尝试将它们链接在一起,链接器将抛出错误

下面是我的代码:

//Module 1
void sth()
{
}
当调用
gcc
时,链接器抛出一个错误:

找到对某事物的多种定义


但是这个链接是否愚蠢到无法区分函数和变量之间的区别?特别是在ELF中有一个符号表,
Elf64\u Symbol
中有一个“type”来区分函数和对象。链接器为什么不使用此信息?

您为链接器提供了多个定义

符号
sth
在两个模块中定义,一个模块为
int
,另一个模块为
void
函数。如果同一符号出现在多个对象文件中,无论其类型如何,如果您尝试将它们链接在一起,链接器将抛出错误

符号只能在一个对象文件中定义。如果要在其他文件中使用它,可以在其他文件中声明,但声明必须与定义匹配


或者,如果您希望某个特定符号仅在其定义的文件中可见,而不在其他文件中可见,则需要向其添加
静态
存储类说明符。

不要诽谤链接器。1) 我怀疑main是否可以用作变量。在我看来,它似乎是某种受限关键字。2) 您已经定义了多个main,GCC是正确的。首先,您将其定义为void函数,然后再次将其定义为int@为了更好地解决这个问题,我已更改了名称。再一次,我必须说,在高级语言如C#,Java中没有这样的问题,而且对于我来说,链接器不能区分函数和对象是很奇怪的。C#&Java没有编译成机器代码。他们有自己的虚拟机/口译员。您可以在那里执行多个这样的定义,因为复杂的环境“支持”您在那里执行代码,并且可以在您不知道的情况下实现各种各样的欺骗。但是当编译成二进制时,它在金属上运行,如果没有技巧,这是不合法的。@APJo-您可以使用
int-foo(void){int-main=1;printf(“%d\n”,main++);return++main;}
作为局部变量。但是,不能使用名为
main
的全局变量。链接器只处理名称。名称表示的对象类型不是材质。您必须创建名为
sth
的不同对象-您不允许这样做(链接器会抱怨)。如果你有
extern-int某物,生活会变得更复杂sth
作为该文件中的
int
,然后在另一个文件中使用函数
sth
。然而,这是未定义的行为-除了不快乐之外,没有任何东西是可以保证的。谢谢你的回答,我确实知道它为什么会抛出错误,但我无法理解为什么链接器不是为了区分函数和对象而设计的,正如我在帖子中提到的,在symtab中实现将是一个非常简单的查找。@amjad在一个文件中,您说它是一件事,在另一个文件中,您说它是另一件事。那么链接器应该选择哪一个呢?即使两者定义为同一类型,您仍然会得到相同的错误。@amjad如果您希望所讨论的符号仅在该文件中是本地的,并且在其他文件中不可见,则需要将其标记为
静态
@amjad:因此,当您使用dlsym在dso中查找符号时,您认为应该返回哪种竞争符号?
//Module 2

int sth= 1;
int func()
{
}