链接器如何控制静态库中定义的main()的可见性?

问题描述 投票:0回答:1

如果我在静态库中定义一个

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__"
),至少我不需要显式地写这个。

c gcc linker
1个回答
0
投票

链接器仅从库中收集未定义的符号。如果扫描库时已定义

main
,则链接器会忽略库中的
main
。所以,这不是看不见的问题,而是看不见的问题。这是一个“被忽略”的问题。

当库中的目标文件同时定义

main
和程序使用的某些其他符号(在链接库之前未定义)时,就会出现问题。假设库中的目标文件同时包含
main
dummy
,并且您的代码调用
dummy
但未定义它(但定义了
main
)。然后您将收到
main
的“多重定义”错误。

© www.soinside.com 2019 - 2024. All rights reserved.