Hôm nay, khi làm việc với một thư viện tùy chỉnh, tôi đã tìm thấy một hành vi lạ. Mã thư viện tĩnh chứa hàm gỡ lỗi main()
. Nó không nằm trong cờ #define
. Vì vậy, nó có mặt trong thư viện. Và nó được sử dụng liên kết đến một chương trình khác có chứa main()
thực.
Khi cả hai liên kết được liên kết với nhau, trình liên kết không đưa ra một lỗi khai báo nhiều cho main()
. Tôi đã tự hỏi làm thế nào điều này có thể xảy ra.Chương trình C này biên dịch và chạy với hai chức năng chính như thế nào?
Để làm cho nó đơn giản, tôi đã tạo ra một chương trình mẫu mà mô phỏng hành vi tương tự:
$ cat prog.c
#include <stdio.h>
int main()
{
printf("Main in prog.c\n");
}
$ cat static.c
#include <stdio.h>
int main()
{
printf("Main in static.c\n");
}
$ gcc -c static.c
$ ar rcs libstatic.a static.o
$ gcc prog.c -L. -lstatic -o 2main
$ gcc -L. -lstatic -o 1main
$ ./2main
Main in prog.c
$ ./1main
Main in static.c
Làm thế nào để "2main" nhị phân tìm mà main
để thực hiện?
Nhưng biên soạn cả trong số họ cùng nhau đưa ra một lỗi khai nhiều:
$ gcc prog.c static.o
static.o: In function `main':
static.c:(.text+0x0): multiple definition of `main'
/tmp/ccrFqgkh.o:prog.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status
bất cứ ai có thể vui lòng giải thích hành vi này?
Nếu bạn chạy 'nm' trên thư viện tĩnh có chứa' main' đầu tiên, nó có biểu thị rằng 'main' được định nghĩa (hiện tại và không có' U' bên cạnh nó) không? – anol
liên kết động sẽ chỉ xem xét các biểu tượng cần thiết và sẽ thả chính trong libstatic.a – tristan
Một số khác có câu trả lời, nhưng tôi muốn nhận xét rằng mã bạn đang biên dịch vi phạm "Quy tắc một định nghĩa" (ODR), có nghĩa là hành vi không xác định. Bạn chỉ cần nhìn thấy những gì mà hành vi không xác định trông giống như cho một trình biên dịch. –