如果我在静态库中定义一个
main()
函数 libmy.a
(就像 flex libl.a
那样),
$ nm /usr/lib/x86_64-linux-gnu/libl.a
libmain.o:
U _GLOBAL_OFFSET_TABLE_
U exit
0000000000000000 T main
U yylex
...
#include <stdio.h>
int main() {
printf("Current file: %s\n", __FILE__);
printf("Current line: %d\n", __LINE__);
return 0;
}
// $ gcc -c libmy.c -o libmy.o
// $ ar rcs libmy.a libmy.o
// $ nm libmy.a
//
// libmy.o:
// U _GLOBAL_OFFSET_TABLE_
// 0000000000000000 T main
// U printf
我什至可以使用这个静态库从空白 C 源文件编写程序。
$ # make an empty C source file
$ touch main.c
$ gcc main.c -L. -lmy
$ ./a.out
Current file: libmy.c
Current line: 5
但是如果我显式定义
main()
函数,那么静态库main()
中的libmy.a
函数似乎是不可见的,否则gcc会报错“redefinition of ‘main’”。这是怎么做到的?
// main.c
#include <stdio.h>
int main() {
printf("Hello World\n");
}
// $ gcc main.c -L. -lmy
// $ ./a.out
Hello World
静态库中似乎没有什么魔法
if
(就像Python中的if __name__ == "__main__"
),至少我不需要显式地写这个。
链接器仅从库中收集未定义的符号。如果扫描库时已定义
main
,则链接器会忽略库中的 main
。所以,这不是看不见的问题,而是看不见的问题。这是一个“被忽略”的问题。
当库中的目标文件同时定义
main
和程序使用的某些其他符号(在链接库之前未定义)时,就会出现问题。假设库中的目标文件同时包含 main
和 dummy
,并且您的代码调用 dummy
但未定义它(但定义了 main
)。然后您将收到 main
的“多重定义”错误。