Программирование >>  Полиморфизм без виртуальных функций в с++ 

1 ... 42 43 44 [ 45 ] 46 47 48 ... 144


Стандартизация 6.2.7. Кто работает в комитете

в комитет по С++ входят люди с разными интересами, ожидания.ми и подготовкой. Одни работают па персональных компьютерах, другие - на UNIX-.маши-нах, третьи - на мейнфреймах и т.д. Одни используют С++, другие - нет. Кто-то хочет, чтобы С++ стал более объектно-ориентированным языком (приче.м объектной ориентированности даются очень разные определения), других бы больше устроило, если бы эволюция С остановилась на ANSI С. Многие, но не все работали с С. Некоторые имеют опыт работы над стандартами, но их меньшинство. Есть профессиональные программисты. Одни обслуживают интересы конечных пользователей, другие поставляют на рынок инструментальные средства. Некоторым интересны крупные проекты. Кому-то необходима совместимость с языком С, кому-то - нет.

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

У мет1я совещательный голос, то есть я представляю свою компанию, но голосует от нее другой человек. Узнать, какие компании представлены в комитете, вы сможете, взглянув на выборку из перечня участников, относящегося к 1990 г.: Amdahl, Apple, AT&T, Bellcore, Borland, British Aerospace, CDC, Data General, DEC, Fujitsu, Hewlett-Packard, IBM, Los Alamos National Labs, Lucid, Mentor Graphics, Microsoft, MIPS, NEC, NIH, Object Design, Ontologies, Prime Computer, SAS Institute, Siemens Nixdorf, Silicon Graphics, Sun, Tandem Computers, Tektronix, Texas Instruments, Unisys, US WEST, Wang, Zortech и др. Надеюсь, вы согласитесь, что отрасль представлена довольно широко.

6.3. Как велась работа

Большая часть работы над стандартами не видна среднему программисту, а когда начинаешь ее описывать, выглядит эта работа скучной и понятной лишь посвященным. Множество усилий тратится на ясное и полное выражение и без того известных всем, но не упомянутых в руководстве возможностей, а также на разрешение вопросов, важных для производителей компиляторов. Ведь это они хотят быть уверены, что правильно поняли то или иное языковое средство. Однако подобные вопросы становятся потом существенными и для программистов, поскольку в основу даже очень тщательно написанной большой программы может быть случайно или намеренно положена возможность, для кого-то не полностью понятная. Если производители компиляторов не договорятся, то программист окажется заложником единственного поставщика, а это уже противоречит моим взглядам на то, каким должен быть С++ (см. раздел 2.1).



Чтобы проиллюстрировать возникающие сложности, я подробно остановлюсь на двух вопросах: разрешении имен и продолжительности функционирования временных объектов. Большая часть усилий комитета тратится на решение именно этих проблем.

6.3.1. Разрешение имен

Самые большие сложности в определении С++ связаны с разрешением имен: с каким точно объявлением связано данное употребление имени. Ниже описана лишь одна проблема такого рода. Она относится к зависимости от порядка объявления членов класса. Рассмотрим пример:

int X,-

class X {

int f() { return x; } int x;

Какой X имеется в виду внутри X: : f () ? А вот другой пример:

typedef char* Т;

class Y {

Т f() { Т а = 0; return а; } typedef int Т;

Какое Т имеется в виду внутри Y: : f () ?

В ARM даются такие ответы: х в определении X: : f () - это X: : х, а определение класса Y содержит ошибку, поскольку смысл Т изменяется после использования в Y: : f ().

Эндрю Кениг, Скотт Тэрнер (Scott Turner), Том Пеннелло, Билл Гиббоне (Bill Gibbons) и еще несколько человек потратили много часов, чтобы найти точные, полные, полезные на практике, логически непротиворечивые и совместимые (со стандартом С и существующим кодом С++) решения. Мое участие в такого рода спорах было ограничено: я как раз раз.мышлял о расширениях.

Сложность проистекает из противоречивости целей:

□ мы хотим, чтобы при синтаксическом анализе можно было ограничиться одним проходом по тексту;

□ изменение порядка следования членов не должно менять се.мантику класса;

□ семантика функции не должна зависеть от того, определена данная функция прямо в объявлении класса или вне его;

□ имена, объявленные во внешней области действия, должны быть видимы и во внутренней (так же, как в С);

□ правила разрешения имен не должны зависеть от того, к чему относится имя.

Если строго следовать всем этим установкам, то синтаксический анализ будет достаточно быстрым, а пользователям не придется заботиться о соблюдении



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

6.3.1.1. Правила разрешения имен в ARM

В ARM эти проблемы решены без особого успеха. Имена из внешней области действия можно использовать непосредственно, а возникающие при этом зависимости от порядка я попытался минимизировать с помощью двух правил:

□ правило переопределения типа: имя типа нельзя переопределять в классе после того, как оно в нем уже использовалось;

□ правило переписывания: функции-члены, определенные в объявлении класса, разбираются так, как если бы они были определены в точке, непосредственно следующей за концом объявления этого класса.

Из-за правила переопределения класс Y дает ошибку:

typedef char* Т;

class Y {

Т f() { Т а = О; return а; }

typedef int Т; ошибка: Т переопределен после использования

Правило переписывания говорит, что class X следует интерпретировать как:

int х;

class X { int f(); int x;

inline int X::f() { return x; } возвращает X::x

К сожалению, не все примеры так просты. Рассмотрим:

const int i = 99;

class Z { int a[i];

int f() { return i; } enum { i = 7 };

Этот пример корректен согласно букве правил ARM, но находится в некотором противоречии их идеям. Два использования i относятся к разным определениям и дают разные значения. Правило переписывания говорит, что i в Z: : f () -это Z: : i и равно 7. Однако для использования i в качестве индекса никакого правила переписывания нет, поэтому имеется в виду глобальное i, равное 99.



1 ... 42 43 44 [ 45 ] 46 47 48 ... 144

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