如何解决在某些情况下,链接器允许多个模块定义具有相同名称的全局符号?
我正在读一本教科书,上面写着:
,我们看到了编译器如何使用看似任意的约定将符号分配给COMMON和.bss。实际上,此约定是由于在某些情况下链接程序允许多个模块使用相同的名称定义全局符号。
但这不是您只能定义一次变量吗?在哪种情况下,链接器允许您多次定义变量?
解决方法
这无时无刻不在发生,因此这是一个实际的构建,涵盖了所有排列:
#- Makefile -----
all: 1 2 3 12 13 23
-./1
-./2
-./3
-./12
-./13
-./23
1: main.o 1.o; $(CC) main.o 1.o -o $@
2: main.o 2.o; $(CC) main.o 2.o -o $@
3: main.o 3.o; $(CC) main.o 3.o -o $@
12: main.o 1.o 2.o; $(CC) main.o 1.o 2.o -o $@
13: main.o 1.o 3.o; $(CC) main.o 1.o 3.o -o $@
23: main.o 2.o 3.o; $(CC) main.o 2.o 3.o -o $@
/* ---- 1.c ----- */
int num;
/* ---- 2.c ----- */
extern int num;
/* ---- 3.c ----- */
int num = 2;
/* ---- main.c --- */
#include <stdio.h>
extern int num;
int main() {
printf("%d\n",num);
return 0;
}
好吧,在您对这个SO归档进行外科解构之后,运行:
make -i all
You should get an output something like:
cc main.o 2.o -o 2
Undefined symbols for architecture x86_64:
"_num",referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: [2] Error 1 (ignored)
./1
0
./2
make: ./2: No such file or directory
make: [all] Error 1 (ignored)
./3
2
./12
0
./13
2
./23
2
因此,首先,程序 2 无法构建。为什么不?因为2.c包含对外部变量(num)的显式声明;因此,当与main.c链接时,两者都对num表示了兴趣;但都没有定义它。
相反,。/ 1和./12都设法定义了它,但是没有为其分配值,因此将其定义为零。 1.c中缺少 extern ,这为链接器耸了耸肩,说,好吧,我将在零部分(bss)中为其分配空间。
./ 3 ./13 ./23证明,在存在定义语句(int num = 2;)的情况下,我们看到了预期的结果。
如果您执行以下操作会遗漏什么,但可能是一个很好的练习:
$(CC) main.c 1.c 1.c 1.c -o 111
?收到错误消息吗?为什么不呢?
This可能会有所启发。
简洁版本:
您可以根据需要“临时声明”一个变量多次。 I.E int i;
但是您只能一次“外部声明”它int i = 1;
您必须阅读文档或等待更详细的答案以获取更多信息。这就是我现在在该主题上发现的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。