Почему я не получаю ошибку «множественное определение» из g ++? - PullRequest
2 голосов
/ 10 января 2011

Я пытался связать свою исполняемую программу с двумя статическими библиотеками, используя g ++.Две статические библиотеки имеют одинаковое имя функции.Я ожидаю ошибку компоновки с «множественным определением» от компоновщика, но я не получил.Может кто-нибудь помочь объяснить, почему это так?

staticLibA.h

#ifndef _STATIC_LIBA_HEADER
#define _STATIC_LIBA_HEADER

int hello(void);

#endif

staticLibA.cpp

#include "staticLibA.h"

int hello(void)
{
    printf("\nI'm in staticLibA\n");
    return 0;
}

вывод:

g++ -c -Wall -fPIC -m32 -o staticLibA.o staticLibA.cpp                                                                             
ar -cvq ../libstaticLibA.a staticLibA.o                                                                                                                           
a - staticLibA.o 

staticLibB.h

#ifndef _STATIC_LIBB_HEADER
#define _STATIC_LIBB_HEADER

int hello(void);

#endif

staticLibB.cpp

#include "staticLibB.h"

int hello(void)
{
    printf("\nI'm in staticLibB\n");
    return 0;
}

вывод:

g++ -c -Wall -fPIC -m32 -o staticLibB.o staticLibB.cpp 
ar -cvq ../libstaticLibB.a staticLibB.o 
a - staticLibB.o

main.cpp

extern int hello(void);

int main(void)
{
 hello();
 return 0;
}

вывод:

g++ -c  -o main.o main.cpp
g++ -o multipleLibsTest main.o  -L. -lstaticLibA -lstaticLibB -lstaticLibC -ldl -lpthread -lrt

Ответы [ 3 ]

1 голос
/ 10 января 2011

Это легко.Объект извлекается из библиотеки только в том случае, если указанный символ еще не был определен.Только один из приветов вытащил (из А).Вы получите ошибки, если будете ссылаться на файлы .o.

1 голос
/ 10 января 2011

Когда компоновщик пытается связать main.o в multipleLibsTest и видит, что hello() не разрешен, он начинает поиск библиотек в порядке, указанном в командной строке. Он найдет определение hello() в staticLibA и завершит поиск.

Это не будет выглядеть в staticLibB или staticLibC вообще.

Если staticLibB.o содержал другой символ, отсутствующий в staticLibA, и он был извлечен в конечный исполняемый файл, вы получите множественное определение ошибки hello, так как отдельные файлы .o извлекаются из библиотеки и два из них будет иметь hello(). После изменения порядка staticLibA и staticLibB в командной строке ссылки эта ошибка исчезнет.

1 голос
/ 10 января 2011

Компоновщик не смотрит на staticLibB, потому что к моменту связывания staticLibA нет невыполненных зависимостей.

...