【发布时间】:2020-08-30 01:31:29
【问题描述】:
下面是我的代码:
//Module 1
void sth()
{
}
//Module 2
int sth= 1;
int func()
{
}
并且在调用gcc 时,链接器会抛出错误:
找到了多个定义。
但是链接是愚蠢的,它无法区分函数和变量之间的区别吗?特别是ELF中有一个符号表,Elf64_Symbol中有一个“类型”来区分函数和对象。为什么链接器不使用这些信息?
【问题讨论】:
-
不要诽谤链接器。 1)我怀疑 main 可以用作变量。在我看来,它是一种受限制的关键字。 2) 你有 multiple-defined main,GCC 是对的。首先,您将其定义为 void 函数,然后再次将其定义为 int !
-
@A P Jo 我已更改名称以更好地解决问题。同样,我不得不说在 C#、Java 等高级语言中没有这样的问题,而且对我来说很奇怪的是链接器无法区分函数和对象。
-
C# 和 Java 未编译为机器码。他们有自己的虚拟机/口译员。你可以在那里做多个这样的定义,因为一个复杂的环境“支持”你的代码在那里执行它,并且可以在你不知道的情况下实现各种诡计。但是当编译成二进制时,它会在 金属上运行,如果没有技巧,这是不合法的。
-
@APJo — 你可以使用
main作为局部变量来拥有int foo(void) { int main = 1; printf("%d\n", main++); return ++main; }。你不能有一个名为main的全局变量。 -
链接器作用于名字——而且只作用于名字。名称所代表的对象的类型不是物质的。您必须使用名为
sth的不同对象 - 您不允许这样做(并且链接器会抱怨)。如果您在一个文件中使用extern int sth;并在该文件中使用sth作为int,然后在另一个文件中使用sth函数,那么生活会变得更加复杂。然而,这是未定义的行为——除了不快乐,没有什么是可以保证的。