Vamos imaginar que tenho uma linha de compilação como a seguinte:
gcc <flags...> -o a.out obj1.o obj2.o
onde ambos obj1.o
e obj2.o
definem void f(int)
. Receberei um erro de definição múltipla (violação da regra de definição única).
Ok, agora imagine o seguinte:
gcc <flags...> -o a.out obj1.o -lstatic_lib
onde ambos obj1.o
e static_lib.a
definem f(int)
. Eu sei que uma biblioteca estática é uma concatenação de .o
arquivos, e para cada símbolo pendente de ser resolvido, for encontrado dentro de qualquer um dos .o
arquivos da biblioteca estática, então o todo .o
que resolver aquele símbolo será vinculado ao binário, junto com qualquer outro símbolo que o mesmo .o
fornece.
Esse comportamento me faz pensar. Imagine que static_lib.a
é composto por dois objetos, static_obj1.o
e static_obj2.o
, onde static_obj1.o
é quem define f(int)
. Como obj1.o
já define f(int)
também, o vinculador não está procurando por ele dentro static_lib.a
e, portanto, static_obj1.o
não será incluído teoricamente, mas, e esta é a questão:
- E se
obj2.o
exigirf2(int)
, quem também é definido porstatic_obj1.o
? O vinculador, após a integraçãostatic_obj1.o
por causa def2(int)
, emitiria um aviso de definição múltipla porf1(int)
ser agora duas vezes?
NOTA: estou marcando C e C++ porque acho que o comportamento é o mesmo para ambos nesse aspecto. Caso contrário, esclareça, estou muito interessado em saber alguma diferença comportamental. Além disso, se o comportamento for muito diferente entre gcc/clang/visual studio/linux/windows, esclareça. Se o comportamento for praticamente o mesmo, concentre-se no gcc em vez do linux.
Sim.
Isto não é regido pela regra de uma definição em C++ ou pela regra correspondente em C. No que diz respeito a esta questão de ligação, essas regras apenas indicam que um programa em conformidade não conterá múltiplas definições. Eles não governam o que acontece ao vincular múltiplas definições. Por exemplo: