|
Программирование >> Обобщенные обратные вызовы
(и их единиц трансляции), и этот рекурсивный процесс продолжается до тех пор, пока не будут выполнены все каскадные инстанцирования (реакция нормального профамм иста в такой ситуации: Какое счастье, что я не занимаюсь реализацией поддержки экспорта в компиляторе! ). Как видите, даже при использовании ключевого слова export внесение изменений в экспортируемый шаблон не позволяет ограничиться перекомпоновкой приложения. В отличие от истинной раздельной компиляции функций, где построение приложения при внесении изменений в одну функцию существенно быстрее, чем полная его перекомпиляция, при использовании экспорта шаблонов сказать заранее, будет ли построение приложения быстрее или медленнее полной его перекомпиляции, в общем случае невозможно. Резюме Итак, теперь вы понимаете, почему невозможно добиться истинной раздельной компиляции шаблонов так же, как это делалось для нешаблонных функций. Многие профаммисты считают, что экспорт означает возможность поставки библиотеки шаблонов пользователю без полного исходного текста, и/или ускорение построения приложения. Ничего подобного export не обещает. Опыт говорит, что должен поставляться весь исходный текст или его прямой эквивалент и что скорость построения приложения оказывается такой же или меньшей, и очень редко - большей, поскольку зависимости оказываются только замаскированы, но не устранены, так что компилятору в общем случае требуется выполнить ту же (если не большую) работу, что и в модели включения. В следующей задаче мы увидим, почему export усложняет С++ и его использование, вплоть до фундаментальных изменений смысла других конструкций языка, порой столь неожиданных, что их просто трудно предвидеть. В этой же задаче будут приведены некоторые советы по эффективному использованию возможностей экспорта (на тот случай, если вам когда-то доведется столкнуться с компилятором, поддерживающим данную возможность). Задача 10. Ограничения экспорта. Часть 2: взаимосвязи, практичность и советы по использованию Сложность: 9 Как export взаимодействует с другими возможностями языка С++ и как эффективно и безопасно его использовать? Вопрос для новичка 1. Когда возможность экспорта появилась в стандарте С++ в ее современном виде? Когда она была впервые реализована? Вопрос для профессионала 2. Поясните, каким образом экспорт изменяет смысл других конструкций С++? 3. Чем именно export мешает профаммисту? 4. В чем заключаются реальные и потенциальные преимущества export? Решение Перед вами вторая часть мини-серии. В предыдущей задаче мы рассмотрели следующие вопросы. Что такое export и для чего предназначена эта возможность С++? Мы провели анализ сходств и различий между моделями включения и экспорта исходного кода шаблонов, и выяснили, в чем состоит отличие этих моделей от встраиваемых и раздельно компилируемых функций и чем оно объясняется. В чем заключаются основные проблемы экспортирования и почему экспортирование работает не так, как ожидают от него профаммисты? Обычно программисты ожидают от возможности экспортирования шаблонов истинной раздельной компиляции шаблонов так же, как и обычных нешаблонных функций. Основные надежды - на то, что экспорт позволит поставлять пользователям библиотеки шаблонов без полного исходного кода определений шаблонов (или их прямого эквивалента), а также что при его использовании увеличится скорость построения приложений. Как мы выяснили, ни одно из этих ожиданий ключевое слово export в применении к шаблонам не оправдывает. Накопленный на сегодняшний день опыт работы с экспортом шаблонов говорит нам, что поставляться исходный текст (или его эквивалент) должен полностью, и что не известно, будет ли время построения приложения при использовании экспорта больше, меньше или останется таким же, как и без него. Почему? Главная причина в зависимостях, которые несмотря на всю маскировку никуда не удаляются, так что компилятор в общем случае должен выполнить как минимум то же количество работы, что и при использовании модели включения шаблонов. Коротко говоря, это ошибка (хотя и вполне естественная) - думать, что экспорт приводит к истинной раздельной компиляции шаблонов в том же смысле, что автор может поставлять только заголовочные файлы с объявлениями шаблонов и объектный код. Экспорт шаблонов скорее похож на библиотеки Java и .NET, в которых байт-код или 1L может быть преобразован в нечто, напоминающее исходный текст. Код этих библиотек не является традиционным объектным кодом. Здесь я хочу рассмотреть следующие вопросы. Текущее состояние экспорта шаблонов. Пути (зачастую неочевидные), которыми экспорт шаблонов приводит к изменению смысла других (казалось бы, никак не связанных с экспортом шаблонов) возможностей языка С++. Некоторые советы по эффективному использованию юзможностей экспорта шаблонов, если вы когда-нибудь столкнетесь с компилятором, который поддерживает эту возможность. Но сначала -- краткий курс истории. Начало: 1988-1996 гг. 1. Когда возможность экспорта появилась в стандарте С++ в ее современном виде? Когда она была впервые реализована? Ответ на поставленный вопрос - 1996 и 2002 годы соответственно. (Если вам кажется, что дата первой реализации той или иной возможности по-хорошему должна предшествовать дате включения ее в стандарт, вы не одиноки, но экспорт шаблонов - не единственный пример, когда стандарт предвосхитил реализацию.) Исходя из вышесказанного и вполне обоснованной критики export, можно начинать кампанию по побиванию камнями людей, которые окопались в комитете по стандарту С++ и принимают такие глупые решения. Но вряд ли стоит впадать в крайности и спешить с выводами. Давайте прислушаемся ко всем за и против , прежде чем принимать решения. Если экспорт не оправдал надежд такого большого количества людей, почему он юоб-ще существует? Причина очень проста. В средине 1990-х годов большинство в комитете считало, что стандарт, в котором отсутствует раздельная компиляция шаблонов (которая давно имелась в С для функций), будет, как минимум, неполным, так что экспорт шаблонов оказался в стандарте из принципиальных соображений. Вспомним также, что в 1995-1996 годах шаблоны были достаточно новой возможностью С++. Впервые шаблоны для С+ + были предложены Бьярном Страуструпом в октябре 1988 года [Stroustmp88]. В 1990 году Маргарет Эллис и Бьярн Страуструп опубликовали The Annotated С++ Reference Manual (ARM) [Ellis90]. В том же году приступил к работе комитет по стандартизации ISO/ANSI С++, выбрав ARM в качестве отправной точки . Эта книга была первым справочником по С++, включавшим описание шаблонов. Это были не тс шаблоны, которые известны нам сегодня. Полное описание этих простейших шаблонов занимало всего 10 страниц текста. В то время основной акцент делался на возможности использования параметризованных типов и функций, а основными примерами применения шаблонов были контейнер List, способный работать с объектами разных типов, и функция sort, которая могла сортировать последовательности разных типов. Кстати, даже тогда не исключалась возможность раздельной компиляции шаблонов. Так, Cfront (компилятор С++ Страуструпа) обладал определенной поддержкой раздельной компиляции простых шаблонов того времени; впрочем, использованный им подход не отвечал требованиям масштабируемости. В 1990-1996 годах разработчики компиляторов С++ работали над реализацией поддержки шаблонов в своих компиляторах и ее развитием, и в то же время комитет по стандарту С++ существенно расширил (и усложнил) семантику шаблонов. Достаточно упомянуть, что полное описание шаблонов в стандарте С++ занимает 133 страницы в 552-страничной книге [Vandevoorde03], посвященной шаблонам и их эффективному использованию (и которую я крайне рекомендую вам прочесть).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |