Как разрешаются внешние символы?

У меня есть два файла 37064544_p1.cpp & 37064544_p2.cpp с таким же содержанием, как показано ниже:

int add(int x,int y)
{
return x+y;
}

Я скомпилировал их, используя

g++ -c 37064544_p2.cpp -o 37064544_p2.o
g++ -c 37064544_p2.cpp -o 37064544_p2.o

и добавил их в архив, используя

ar -rsc lib37064544pf.a 37064544_p1.o 37064544_p2.o

А также

$ nm -s lib37064544pf.a

дает мне :

Archive index:
_Z3addii in 37064544_p1.o
_Z3addii in 37064544_p2.o

37064544_p1.o:
0000000000000000 T _Z3addii

37064544_p2.o:
0000000000000000 T _Z3addii

а также

$ ar -t lib37064544pf.a

дает мне

37064544_p1.o
37064544_p2.o

У меня есть драйвер, который вызывает _Z3addii функция, которая скомпилирована с

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. -l37064544pf

Результат

Sum : 11

Вопросы

  1. Как символ _Z3addii решен?

    • Это в соответствии с индексом архива?
    • Это в соответствии с порядком, в котором мы заполняем архив, используя ar?
  2. Как я могу изменить этот заказ?

  3. Как я могу предотвратить ar иметь дубликаты символов?

Компилятор: g ++ 4.6.3

10

Решение

Как разрешается символ _Z3addii?

Реализация может делать все, что угодно, вы нарушаете одно определение правила.

Реально он перестанет искать любой заданный символ после первого совпадения, которое предположительно следует порядку, в котором файлы были вставлены в архив.

Как я могу изменить этот заказ?

С ar Вы можете использовать a (после) и b (до) модификаторы для размещения объектных файлов в архиве при их вставке, но вы все равно нарушаете ODR.

Как я могу предотвратить дублирование символов в ar?

Вы не можете, насколько я знаю, ar является относительно глупым и по уважительной причине, так как некоторые языки допускают использование идентичных символов, поэтому у вас нет ошибок при связывании с архивом (для нарушений ODR не требуется диагностика).

Вы можете либо заставить ld читать весь архив

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. \
-Wl,--whole-archive -l37064544pf -Wl,--no-whole-archive

Или вы можете сделать частичную ссылку вместо традиционного архива, который выдаст ошибку при наличии дубликатов

ld -r -o lib37064544pf.a 37064544_p1.o 37064544_p2.o
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]