(Среда: gcc 4.6, c ++ 11, glibc 2.13, binutils 2.21)
Пожалуйста, обратите внимание на следующую демонстрацию "связывания" в качестве фона:
foo.h:
#pragma once
#include <iostream>
void foo();
foo1.cpp:
#include "foo.h"
void foo()
{
std::cout << "foo1";
}
foo2.cpp:
#include "foo.h"
void foo()
{
std::cout << "foo2";
}
main.cpp:
#include "foo.h"
int main()
{
foo();
}
Makefile:
compile: main.o foo1.o foo2.o
case1: compile
g++ -o case1.x main.o
case2: compile
g++ -o case2.x main.o foo1.cpp
case3: compile
g++ -o case3.x main.o foo1.o foo2.o
clean:
rm *.o *.x
У нас есть следующее объявление функции:
void foo();
и у нас есть несколько его определений, одно в foo1.cpp, а другое в foo2.cpp.
Компилируем файлы .cpp в файлы .o:
$ make compile
Нет проблем, создаются main.o, foo1.o и foo2.o.
Случай 1
Затем мы пытаемся связать только main.o:
$ make case1
error: undefined reference to 'foo()'
Хорошо, main.o ссылается на foo, но определение не было связано.
Случай 2
Теперь мы пытаемся связать main.o и foo1.o
$ make case2
В foo1.o есть единственное определение foo, поэтому он связывается без ошибок.
Случай 3
Теперь мы пытаемся связать main.o foo1.o и foo2.o
$ make case3
error: multiple definition of 'foo()'
Компоновщик находит два определения foo в foo1.o и foo2.o, поэтому вместо того, чтобы брать случайное, он быстро завершается с ошибкой и не связывает.
Вопросы
Мои вопросы:
Можно ли отметить определение версии foo для foo1.cpp (возможно, с каким-то атрибутом gcc или прагмой) как "слабое"? Это означает, в частности, что я хочу, чтобы поведение case 1 и case 2 оставалось таким же, в то время как поведение case 3 изменяется на успешное связывание без предупреждения или ошибки, а определение foo в foo2.cpp связано (переопределение "слабого" определения в foo1.cpp).
Можно ли проверить во время выполнения (и присвоить логической переменной), была ли связана слабая версия foo или сильная (без очевидного выполнения функции). т.е. реализовать функцию в основном следующим образом.
template<typename FunctionPtr> bool is_weak_linked(FunctionPtr fp);
is_weak_linked (foo) должен возвращать true в случае 2 и false в случае 3.
is_weak_linked
? Или вообще слабая связь? Почти наверняка есть более элегантное или более портативное решение любой проблемы, которую вы пытаетесь решить. - person Managu   schedule 02.02.2012