Несколько определений символов и статических библиотек - PullRequest
0 голосов
/ 11 мая 2018

Я столкнулся с несколько неожиданным поведением процесса связывания, и я хотел бы попросить разъяснений.

Кажется, что связывание с объектным файлом и со статической библиотекой, содержащей тот же набор символов,не эквивалентноПервое приводит к ошибке 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

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Компоновщик ищет определение в архиве, только если он еще не нашел определение. В вашем случае
$ gcc c.o a.o -L./ -lb # Works fine?
работает, потому что компоновщик уже нашел определение myfunc () в a.c. Быстрая проверка этого состоит в том, чтобы включить распечатки в a.c и b.c, чтобы проверить, какой myfunc () используется при запуске вашего исполняемого файла. Подробнее здесь .

0 голосов
/ 11 мая 2018

Библиотека - это просто набор объектных файлов. Проверка нескольких определений не производится.

Исполняемый файл может иметь только одно определение функции. В процессе компоновки компоновщик фиксирует вызовы (адреса) функций в объектах. Если он запрашивает второе определение той же функции (имени), он не знает, какую из них использовать.

Обратите внимание, что наличие нескольких определений в статической библиотеке обычно также приводит к тому, что компоновщик жалуется на несколько определений, поскольку он не знает, какой объект библиотеки использовать. Наличие нескольких определений в нескольких библиотеках можно решить, задав компоновщику порядок библиотек: он будет использовать первый встреченный символ.

...