Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Дублирование кода шаблонов в разных модулях


Автор: Alexeis 23.3.2008, 13:43
  Шаблоны обычно реализуются в заголовочных файлах. Допустим в n файлах используются шаблонный класс vector<int>. Теперь представим ситуацию, билдим каждый модуль отдельно, соответственно создается n *.obj файлов, каждый из которых содержит свою реализацию vector<int>.
  Вопрос в том, как в этом случае поступит линкер? Не ужели он продублирует реализацию шаблона vector<int> в каждом из модулей? 

Автор: Daevaorn 23.3.2008, 13:46
Цитата(Alexeis @  23.3.2008,  14:43 Найти цитируемый пост)
Вопрос в том, как в этом случае поступит линкер? Не ужели он продублирует реализацию шаблона vector<int> в каждом из модулей?  

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

Автор: MAKCim 23.3.2008, 14:24
Цитата(Daevaorn @  23.3.2008,  13:46 Найти цитируемый пост)
Линкер мержит код в таких случаях. Он даже может мержить  для разных типов, но одинаковых по конечному коду. Умный в общем

а почему тогда тут не мержит
Код

// a.cpp
int get() {
    return 0;
}

Код

// b.cpp
int get() {
    return 0;
}

Код

// main.cpp
extern int get();

int main() {
    return get();
}

Код

# g++ -c a.cpp b.cpp
# g++ main.cpp -o main a.o b.o

?

Добавлено через 5 минут и 4 секунды
вопрос снят
разный биндинг символов

Автор: Alexeis 23.3.2008, 14:32
  Значит он включает первый модуль где встретит vector<int>, а в последующих заменяет вызовы текущего объектного файла, на вызовы из первого. Но тогда получается, что компилятор должен включать в obj файл полную реализацию класса, а не только те функции класса, которые реально используются. 
  Или опять же, за  удаление неиспользуемых функций класса ответственен линкер?

Автор: bsa 23.3.2008, 14:58
Alexeis, там смысл такой, что в результирующий бинарник помещаются только тот код, который используется.
Кстати, компилятор не создает код для неиспользуемых методов шаблонов.

Автор: Daevaorn 23.3.2008, 15:07
Цитата(Alexeis @  23.3.2008,  15:32 Найти цитируемый пост)
Значит он включает первый модуль где встретит vector<int>, а в последующих заменяет вызовы текущего объектного файла, на вызовы из первого. Но тогда получается, что компилятор должен включать в obj файл полную реализацию класса, а не только те функции класса, которые реально используются. 
  Или опять же, за  удаление неиспользуемых функций класса ответственен линкер? 

В конечном счете в исполняемом файле нет модулей, там просто сплошной код. Модули остаются на уровне линковки.

Автор: Alexeis 23.3.2008, 15:26
Цитата(bsa @  23.3.2008,  13:58 Найти цитируемый пост)
Кстати, компилятор не создает код для неиспользуемых методов шаблонов.

  Как же линкер тогда собирает класс?  smile 

Представим себе что 1й модуль использует методы a, b и c из шаблонного класса, 1 модуль использует b, c и d, 3й использует с, d и f и т.д. И все это один и тот же шаблонный класс. 
  Полного откомпилированного экземпляра у него нет. Значит чтобы собрать класс до кучи понадобиться пропарсить все объектные модули и либы, выдрать из всего этого код всех методов, потом править все ссылки... как-то не правдоподобно звучит.

Автор: bsa 23.3.2008, 15:33
Цитата(Alexeis @ 23.3.2008,  15:26)
Полного откомпилированного экземпляра у него нет. Значит чтобы собрать класс до кучи понадобиться пропарсить все объектные модули и либы, выдрать из всего этого код всех методов, потом править все ссылки... как-то не правдоподобно звучит.

Вообще-то линкер все это и парсит. Если находит что-то используемое, но не определенное, то выдает ошибку.
Кстати, на этапе линковки понятия "класс" уже нет. Есть понятие "символ", который ссылается на переменную или функцию.

Автор: Alexeis 23.3.2008, 15:58
  Спасибо вопрос исчерпан.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)