Страницы

Поиск по вопросам

воскресенье, 21 октября 2018 г.

export/extern&шаблоны

Интересно, почему export шаблонов deprecated? Знаю только то, что никто не реализовал ее в своих компиляторах кроме компании Edison Design Group, но потом и они признали что это полная "лажа". В чем были сложности?
В новом стандарте, вместо export tempate ввели extern template. Зачем? Некрофилия?


Ответ

Проблема следующая. Шаблоны C++ — функциональность, гораздо более близкая к макросам, чем к функциям/классам. Это чистая конструкция времени компиляции. Невозможно «скомпилировать» шаблон так, чтобы потом можно было просто подлинковать его к программе (в отличие от функций и классов.) Поэтому хранить в объектном файле всё равно придётся текст, никакого выигрыша это не даст.
Почему невозможно заранее скомпилировать шаблон в объектный код? Посмотрите на вот такой простой код:
template void f(T1 t1) { T2 t2 = t1; }
Это копирующая инициализация. В зависимости от типов T1 и T2, а также от видимости других типов в точке использования она может компилироваться в вызов наилучшего из доступных конвертирующего конструктора (и преобразование типа T2 к типу аргумента этого конструктора, если они не совпадают), оператора конверсии, стандартные конверсии, числовые конверсии, включая потерю точности и смену представления между плавающей точкой и целыми числами.
Как вы думаете, можно ли закодировать всё это в объектном коде (то есть, по существу на ассемблере), не зная на момент компиляции типы T1 и T2?

Вот есть целая статья от EDG, с анализом, почему экспорт шаблонов не взлетит и не стоит свеч: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf. И ещё одна: http://blogs.msmvps.com/vandooren/2008/09/24/c-keyword-of-the-day-export/
Более подробно, проблемы следующие (перевёл из статьи EDG):
У EDG на одну эту фичу ушло 1,5 лет на дизайн и 3 года на имплементацию (сравнение: на всю Джаву — только два года). При этом EDG — не «какая-то» компания, у них хорошие разработчики, с многолетним опытом разработки компиляторов C++. Типичная структура компилятора C++ не подходит для имплементации этой фичи. Пришлось переделывать дизайн компилятора, и скорее всего это же придётся сделать всем другим разработчикам, если экспорт станет обязательной частью стандарта. Многие ошибки, которые без экспорта шаблонов было не обязательно детектировать (например, нарушение ODR-rule, которое по стандарту всего лишь UB), с экспортом фактически становится обязательно отлавливать. Форматы промежуточных файлов придётся полностью менять. Эта фича не приносит настолько уж большой пользы:
Считается, что с экспортом шаблонов более не нужно будет поставлять исходный код библиотек. Это не так. Поскольку шаблоны работают на уровне, близком к синтаксическому, то вместе с библиотеками придётся поставлять либо текст шаблонов, либо его прямой эквивалент (например, синтаксическое дерево), поскольку во время инстанциации шаблонов нужна вся эта информация. Считается, что с экспортом шаблонов ускорится компиляция и уменьшится количество зависимостей. Это не так, потому что (вследствие синтаксической природы шаблонов) экспортированный шаблон невозможно заранее скомпилировать. Компиляцию шаблона (по меньшей мере от уровня синтаксического дерева) придётся всё равно повторять, на этот раз на этапе компоновки. Таким образом, компилятору придётся выполнить по меньшей мере ту же работу, что и без экспорта. Единственный реально сработавший плюс экспорта шаблонов — то, что макросы не покидают границы единицы трансляции. (В случае без экспорта, макросы, определённые в файле с шаблоном, «видны» всем, кто использует шаблон.) Этого положительного эффекта, однако, можно добиться при помощи более строгой организации кода; также существуют другие, более лёгкие и эффективные методы решения этой проблемы на уровне стандарта языка.

Комментариев нет:

Отправить комментарий