Программирование >>  Обобщенные обратные вызовы 

1 ... 16 17 18 [ 19 ] 20 21 22 ... 84


в начале и средине 1990-х годов комитет по стандарту С++ пытался сделать шаблоны более интеллектуальными и практичными. Члены комитета оказались сами несколько удивлены чрезвычайной гибкостью и определенной моистрообразностью того, что получилось. Как известно, шаблоны представляют собой полный в смысле Тьюринга метаязык, который позволяет написать профамму любой сложности, которая будет полностью выполнена на этапе компиляции. Современные технологии .мстапрогра.ммирования с использованием шаблонов и дизайн современных библиотек оказались неожиданными для людей, которые дали программистам эти самые шаблоны. Упо.мянутые технологии были практически неизвестны в 1990-1996 годах. Они не использовались до 1994 года, когда Степанов впервые представил свою первую версию STL комитету. В 1995 году эта библиотека была воспринята как большое достижение - это сегодня STL всего лишь библиотека контейнеров и алгоритмов.

Вот почему я утверждаю, что в 1995-1996 годах шаблоны были достаточно новой возможностью С++. Современные шаблоны уже существовали почти в том же виде, что и сегодня, но даже их первооткрыватели не могли полностью представить, на что они способны. Сообщество С++ было в те годы существенно меньше сегодняшнего, только немногие компиляторы поддерживали шаблоны в объеме большем, чем было описано в ARM, а сама поддержка была слабой и по сути бесполезной. В качестве примера - в то время с первой версией STL смог справиться только одии-единственный коммерческий компилятор.

Итак, все программистское сообщество в целом и комитет в частности имели только сравнительно небольшой опыт работы с шаблонами, причем в основном с более простыми шаблонами ARM. Шаблоны в 1996 году уже не были в зачаточном состоянии, но они все еще находились в стадии роста и формирования.

Как видим, комитет по стандарту С++ принял решение о включении экспорта шаблонов в стандарт еще на первых этапах развития, при ограниченном опыте работы с шаблонами.

1996 г.

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

В 1996 году в комитете наблюдалась скоординированная поддержка удаления понятия раздельной ко.мпиляции шаблонов из стандарта. В частности, утверждалось, что модель раздельной компиляции шаблонов никогда не была реализована в действительности, так что было не понятно, будет ли она работать так, как предполагается. Некоторые разработчики компиляторов С++ реализовали различные виды организации исходных кодов шаблонов, но среди них не было поддержки export; это была совершенно новая экспериментальная модель, за которой не было никакого реального опыта. Более того, в то время вниманию общественности было представлено несколько статей (которые ретроспективно можно назвать провидческими), в которых детально расписывались некоторые из потенциальных недостатков модели экспортирования, описанной в черновом варианте стандарта.

В частности, все производители компиляторов единодушно воспротивились включению модели раздельной компиляции в стандарт, поскольку, по их мнению, в тот момент нельзя было сказать, что из этого получится. У них была масса претензий к имеющимся редакциям этой части стандарта (как с ключевым словом export, так и без него), а кроме того, они не ощущали себя достаточно опытными в данном вопросе для того, чтобы реализовать экспорт шаблонов на практике или предложить



приемлемую альтернативу (не говоря уж о недостатке времени - планировалось выпустить окончательный вариант стандарта в следующем, т.е. 1997 году). Из-за всего этого производители компиляторов единогласно не хотели спешить с включением модели разделения в первый стандарт [С++98]. Вместо этого предлагалось обкатать идею как следует и подготовить ее к включению в следующий стандарт С++. Они не отказывались от идеи раздельной компиляции в принципе, но чувствовали, что в том виде, в котором ее предложено внести в стандарт, она еще сыровата.

Тем не менее, они проиграли, и ключевое слово export применительно к шаблонам оказалось в стандарте. Как я говорил ранее, большинство (незначительное) в комитете считало, что невозможно выпускать стандарт, в котором нет раздельной компиляции шаблонов, в то время как для обычных функций в С такая раздельная компиляция давно имеется и широко применяется. Несколько производителей компиляторов уже поэкспериментировали с различными видами раздельной компиляции шаблонов, и эта идея казалась, в принципе, обоснованной. Словом, export остался в стандарте из принципиальных соображений, и из этих же соображений не следует чернить его сверх меры.

Подчеркнем, что ведущие производители компиляторов были не против принципа раздельной компиляции шаблонов вообще, а против конкретной формулировки в стандарте языка. Они полагали, что следовало дать дополнительное время на анализ этого вопроса и принятие верного решения. Хотя некоторые из экспертов, которые в 1996 году голосовали за включение export в стандарт языка, сейчас считают это решение ошибочным, поставленные тогда цели были вполне правильными. Остается надеяться, что со временем они будут достигнуты. А пока что нам остается набираться опыта с помощью первого компилятора, который реализовал эту возможность (Comeau 4.3.01, 2002 год).

Опыт работы с экспортом

Единственный в мире производитель компилятора с поддержкой export для шаблонов - EDG - сообщил о том, что это наиболее сложная в реализации возможность С + + , которая требует объема работы не меньшего, чем любые три другие возможности языка (например, пространства имен или шаблоны-члены классов). Потребовалось более трех человеко-лет работы только для кодирования и тестирования, не считая проектирования. Для сравнения - реализация языка Java теми же тремя программистами потребовала только два человеко-года.

Почему же поддержка export так сложна и трудно реализуема? Две основные причины можно сформулировать следующим образом.

1. Экспорт базируется на поиске Кёнига. Большинство компиляторов все еще не в состоянии реализовать корректный поиск Кёнига даже в пределах одной единицы трансляции (попросту говоря, в одном исходном файле). Экспорт же требует выполнения поиска Кёнига в нескольких единицах трансляции. (Дополнительную информацию о поиске Кёнига можно найти в [SutterOO].)

2. Концептуально экспорт требует от компилятора одновременной работы с несколькими таблицами символов. Инстанцирование экспортированного шаблона может вызвать каскадные инстанцирования в других единицах трансляции, и каждое инстанцирование должно иметь возможность обратиться к объектам, которые существуют (или как бы существуют ) при синтаксическом анализе определения шаблона. В С++ уже достаточно сложна работа только с одной таблицей символов.

Обсуждение этого вопроса было бурным, и мнения членов комитета разделились. Так, в марте 1996 года голоса разделились как 2 к 1 против раздельной компиляции шаблонов; однако уже в июле того же года, когда ключевое слово export было внесено в стандарт, перевес голосов в пользу такого решения составил 2 к 1.



а в случае экспорта шаблонов приходится иметь дело с произвольным количеством таких таблиц.

До чего доводит экспорт

2. Поясните, каким образом экспорт изменяет смысл других конструкций С++?

Ключевое слово export порой неожиданным образом влияет на другие возможности языка. Многие из них никак не упомянуты в стандарте. В частности, export экспортирует не только шаблон, с которым употребляется.

Если некоторые функции и объекты в безымянных пространствах имен используются в экспортируемых шаблонах, то теперь они должны быть доступны не только в пределах своих единиц трансляции. Аналогично, некоторые статические функции и объекты, используемые в экспортируемых шаблонах, которые ранее были видимы только в пределах своего файла, теперь должны иметь внешнее связывание (или, по крайней мере, вести себя так, как будто они им обладают). Это противоречит предназначению безымянных пространств имен и описания функций и объектов как статических, что должно делать их имена строго внутренними для соответствующих единиц трансляции. (Хотя статические функции и объекты объявлены устаревшей и нежелательной конструкцией языка, и вы должны вместо описания static использовать безымянные пространства имен, они остаются частью стандарта С++.)

Разрешение перегрузки также должно быть способно выполнять разрешение с использованием имен из различных единиц трансляции - включая перегруженные имена из произвольного количества безымянных пространств имен. Главное преимущество размещения внутренних функций в безымянных пространствах имен (или объявление их статическими) состоит в их скрытии , так что вы можете давать им простые имена, не беспокоясь о конфликтах имен или перегрузке при использовании нескольких исходных файлов. Теперь же эти функции могут участвовать в разрешении перегрузки при их использовании в экспортируемых шаблонах. Таким образом, для скрытия имен функций и объектов, используемых в экспортируемых шаблонах, недостаточно их размещения в безымянных пространствах имен, что, конечно же, противоречит изначальной идее безымянных пространств имен и статических объявлений.

Возникают также новые разночтения и потенциальные нарушения правила одного определения. Например, класс может иметь несколько друзей в различных единицах трансляции, и в инстанцировании могут участвовать объявления этого класса из разных единиц трансляции. Если это так, то какой именно набор правил доступа следует применять? Это может показаться очень мелким вопросом, а многие подобные ошибки - безвредными, но последствия нарушения правила одного определения становятся все более существенными у ряда распространенных компиляторов (см. один из примеров в [Sutter02c]).

Трудность корректного использования

3. Чем именно export мешает программисту?

Корректно использовать экспортируемые шаблоны несколько сложнее, чем обычные. Вот три примера, иллюсгрируюшие это утверждение.

Пример I. Становится проще, чем раньше, написать программу с трудно предсказуемым смыслом. Так же, как и в модели включения шаблонов, зачастую экспортируемый шаблон имеет различные пути инстанцирования и каждый из них имеет свой собственный контекст. На возражение наподобие того, что та же проблема наблюдается и в случае функций, определенных в заголовочном файле, т.е. встраиваемых (inline).



1 ... 16 17 18 [ 19 ] 20 21 22 ... 84

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика