|
Программирование >> Полиморфизм без виртуальных функций в с++
3 диалектов ANSI С. При подсчете учитывалось число неопределенных и зависящих от реализации аспектов, а 3 было выбрано в качестве основания как среднее число вариантов каждого такого аспекта. Естестветю, средний пользователь, жаждущий совместимости с С, понимал под ней совместимость с локальным диалектом. Это виделось важной практической проблемой, которой я и мои друзья уделяли много внимания. Администраторам и продавцам до нее было меньше дела; они либо не вполне понимали технические детали, либо их интерес к С++ объяснялся желанием привязать пользователей к своим программным и аппаратным решениям. С другой стороны, разработчики С++ в Bell Labs независимо от того, в каком подразделении они работали, были эмоционально преданы концепции переносимости [Johnson, 1992] и противились требованиям администрации закрепить конкретный диалект С в определении С++. У вопроса о совместимости была и другая, более важная сторона. Какими параметра.ми С++ должен отличаться от С, чтобы достичь своих основных целей? И в чем именно С++ должен быть совместим с С для достижения этих же целей? Оба аспекта существенны, и при переходе от С with Classes к С++ пересмотр концепций производился в обоих направлениях. Медленно и мучительно было выработано соглашение о том, что между С++ и ANSI С (когда появится стандарт) не будет неоправданных несовместимостей [Stroustrup, 1986], но тем не менее понятие вынужденной несов.местимости имеет право на существование. Естественно, вопрос о том, что считать вынужденной несовместимостью , вызывал много споров и отнимал у меня непропорционально много времени и сил. Впоследствии появилась формулировка - С++: настолько близко к С, насколько возможно, но не ближе , по названию работы, написанной совместно Эндрю Кенигом и мной [Koenig, 1989]. Один из показателей успеха такой стратегии - все примеры из книги K&R2 [Kernighan, 1988] написаны на С, который является подмножеством С++. Примеры программ из K&R2 тестировались с помощью компилятора Cfront. Некоторые заключения о модульности и о том, как собирать программу из отдельно скомпилированных частей, были изложены в первой редакции справочного руководства по С++ [Stroustrup, 1984]: □ имена являются закрытыми, если не объявлены открытыми; □ имена локальны в файле, где они определены, если явно не экспортированы из него; □ типы контролируются статически, если такой контроль не подавлен; □ класс составляет область действия (откуда следует, что классы могут быть вложенными). Первый пункт не влияет на совместимость с С, остальные приводят к некоторым расхождениям: □ имя нелокальной функции или объекта в С по умолчанию видимо в других единицах трансляции; □ в С необязательно объявлять функции перед использованием, и по умолчанию проверка типов при вызове не производится; □ имена структур в С не вкладываются (даже если лексически они вложены); □ в С++ есть только одно пространство имен, тогда как в С с каждым тэгом структуры связано отдельное (см. раздел 2.8.2). Сегодня баталии по поводу совместимости кажутся мелки.ми и скучными, но некоторые из поднятых тогда проблем не решены до сих пор. Полагаю, причина, по которой эти войны так затянулись и не принесли окончательного результата, заключается в том, что мы не затрагивали более глубоких вопросов о различии целей С и С++ и видели в совместимости множество несвязанных проблем, к каждой из которых следует подходить индивидуально. Типичный пример - наименее значи.мый вопрос о пространствах имен потребовал больше всего усилий и, в конце концов, был решен путем-компромисса [ARM]. Мне пришлось нарушить концепцию класса как области действия и принять решение С, иначе не разрешалось выпускать версию 1.0. При этом я не понимал, что структура в С не составляет области действия, поэтому конструкция struct outer { struct inner { int i ; int j ; struct inner a = { 1 }; вполне допустима. Более того, такого рода код встречается в стандартных заголовочных файлах системы UNIX. Когда данная проблема всплыла, уже ближе к концу известных баталий , у меня не было времени подробно изучать все последствия этого решения С. Гораздо проще было согласиться, чем затевать новые споры. В 1989 г., после многих технических сложностей и недовольства пользователей, вложенные области действия классов снова были введены в С++ [ARM] (см. раздел 13.5). Ожесточенные споры привели к тому, что для С++ был одобрен усиленный контроль типов при вызове функции (без модификаций). Неявное нарушение статического контроля типов стало первым случаем вынужденной несовместимости С и С++. Комитет ANSI С одобрил облегченный вариант правил и нотации C++ в этой области и объявил устаревшими такие виды использования, которые не отвечают правилам С++. Пришлось принять правило С о том, что глобальные имена по умолчанию видимы в других единицах трансляции. Просто не было поддержки для правила, более жестко ограничивающего область видимости имен. Это означало, что в С++, как и в С, не будет механизма для выражения модульности на уровне выше класса или файла. Это послужило причиной многих жалоб, пока комитет ANSI/ISO не принял пространства имен (см. главу 17) в качестве механизма, позволяющего избежать непреднамеренного совмещения имен. Однако Дуг Макилрой и другие возражали, что С-программисты не оценят язык, где каждый объект и функцию. которые должны быть доступны из другой единицы трансляции, придется явно объявлять таковыми. Возможно, в то время они были правы и уберегли меня от серьезной ошибки. В любом случае теперь я убежден, что первоначальное решение, предлагавшееся для С++, было не слишком изящны.м. Обсуждение вопросов сов.местимости раскололо пользователей на два противоборствующих лагеря, и члены каждого из них были абсолютно убеждены в справедливости своей точки зрения. Первый лагерь требовал стопроцентной совместимости, часто не осознавая ее последствий. Например, многие из поборников полной совместимости с недоумением узнавали, что это приведет к несовместимости с уже существующим С++, в результате чего перестанут компилироваться десятки миллионов строк написанного на С++ кода. Во многих случаях требование стопроцентной совместимости исходило из предположения, что у С++ мало пользователей. Нередко за этим требованием стояло желание скрыть свое незнание С++ или неприятие некоторых его новых возможностей. В другом лагере объявляли, что проблемы совместимости с С не существует вовсе, и требовали введения таких возможностей, которые вызвали бы серьезные неудобства у всех, кто хотел писать на смеси языков С и С++. Разумеется, чем более экстремистскими были притязания, исходящие из одного лагеря, тем глубже окапывались представители другого, боясь потерять те возможности языка, в которых были заинтересованы. В тех случаях (к счастью, почти всегда), где учитывались истинные интересы людей и реальные примеры использования С и С++, споры обычно заканчивались конструктивным рассмотрением деталей компромиссного решения. На организационном собрании комитета ANSI X3J16 Ларри Рослер, первый редактор ко.митета ANSI С, объяснил скептически настроенному Тому Пламу (Тот Plum), что С++ - это С, каким мы пытались, но не смогли его сделать . Возможно, данное утверждение чересчур сильно, но для общего подмножества С и С++ оно недалеко от истины. 3.13. Инструменты для проектирования языка Рассказывая о дизайне и эволюции С++, я почти не уделил внимания теории и инструментам более сложным, чем обычная классная доска. Для работы над грамматикой я пытался использовать YACC (генератор синтаксических анализаторов ЬАЬК(1)-фамматик [Aho, 1986]), но потерпел неудачу из-за особенностей синтаксиса С (см. раздел 2.8.1). Пробовал применить денотационную семантику, тоже неуспешно. Рави Сетхи (Ravi Sethi), занимавшийся этой проблемой, понял, что не может выразить семантику С подобным способом [Sethi, 1980]. Основной трудностью была нерегулярность С и большое число зависящих от реализации и неопределенных аспектов. Много позже комитет по стандартизации ANSI/ISO С++ призвал экспертов по формальным определениям растолковать свои методы и инструментарий и высказать мнение о то.м, в какой мере формализованный подход к определению С++ будет полезен нам при стандартизации. Я знакомился также с формальными спецификациями языков ML и Modula-2, чтобы понять, поможет ли формальный подход получить более короткое и изящное описание, чем описание на обычном английском языке. Не ду.маю, что формальное
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |