Я столкнулся с несколько неожиданным поведением процесса связывания, и я хотел бы попросить разъяснений.
Кажется, что связывание с объектным файлом и со статической библиотекой, содержащей тот же набор символов,не эквивалентноПервое приводит к ошибке multiple definition
, тогда как последнее, кажется, связывается правильно.
Минимальный пример
Файл a.c
и b.c
одинаковы:
void myfunc() {
}
Файл c.c
является «основным»:
void myfunc();
int main()
{
myfunc();
return -1;
}
Рабочий процесс компиляции идет следующим образом:
$ gcc -c a.c b.c c.c
$ gcc c.o a.o b.o # Breaks!
a.o: In function `myfunc':
a.c:(.text+0x0): multiple definition of `myfunc'
b.o:b.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
$ ar rvs libb.a b.o
$ gcc c.o a.o -L./ -lb # Works fine?
Мой вопрос здесь: почему разрешена вторая ссылка иво-первых, если символы, содержащиеся в объекте и статической библиотеке, совпадают?
Кроме того, это поведение компилятора или системы специфично?
Расширение
Этопотенциально отдельный вопрос, но, возможно, полезно поставить его здесь.Проблема множественных ссылок вновь возникает со статической библиотекой, если в файле b.c
определена дополнительная функция, например, для bc, содержащей
void myfunc() {
}
void anotherfunc() {
}
И теперь этап связывания прерывается с той же ошибкой, что и раньше:
gcc b.c
gcc -L./ c.o -lb a.o
a.o: In function `myfunc':
a.c:(.text+0x0): multiple definition of `myfunc'
.//libb.a(b.o):b.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit stat