Б. Страуструп - Дизайн и Эволюция C++. 2006 (1160775), страница 43
Текст из файла (страница 43)
Другой способ — ввести явные операции для задания установок, отличных от подразумеваемых: ПИИИИИИ11 Стандартизация Существенное преимущество такого способа состоит в том, что он облегчает передачу объектов, представляющих аргументы, между различными частями программы. Естественно, все эти приемы можно использовать в любом сочетании. В совокупности они позволяют сократить список аргументов и, следовательно, свести па нет потребность в именованных.
Число аргументов можно еще больше сократить, если воспользоваться типом 1'о~пц вместо того чтобы передавать пары координат. чоЫ* вевсору(чоЫ*геэсг1сс з1, сопзг чоьц* э2, згае с ц1 Поскольку уже сказано, что у э1 нет псевдонимов, нет необходимости указывать гевггъсс еще и для э2. Ключевое слово геэсгусс применяется к оператору * точно так же, как модификаторы сопэс и чо1ас11е. Это предложение должно устранить преимушество Гогггап в эффективности, приняв в С правила, действующие в Гогггап (правда, лишь выборочно). Комитет по С++, внимательно относившийся к любому предложению, способному повысить эффективность языка, потратил немного времени на обсуждение данного предложения, но все же оно было отклонено, насколько я помню, единогласно. Вот основные мотивы; з расширение небезопасно.
Если объявить указатель как геэсгзсс, то компилятору позволено предполагать, что у него цет псевдонимов. Однако б.5.2. Ограниченные указатели Компилятору Рогггап разрешено предполагать, что два массива, переданных функции в качестве аргументов, не перекрываются. Функция С++ не вправе делать таких допущений. В результате подпрограмма, написанная на Еогггап, оказывается на 15-30% быстрее в зависимости от качества компилятора и машинной архитектуры.
Особенно заметную экономию дают векторные операции на машинах, имеющих специальную векторную аппаратуру (например, Сгау). Учитывая повышенное внимание к эффективности С, все вышесказанное рассматривалось, как досадная оплошность. В комитет АНБ1 С поступило предложение решить эту проблему с помощью механизма, названного поа11аэ. При валичи и этого ключевого слова считалось бы, что у указателя нет псевдонимов (то есть никакие два указателя не указывают на одну и ту же область памяти). К сожалению, предложение поступило слишком поздно и в очень непроработанном виде. Это обстоятельство побудило Денниса Ричи написать открытое письмо, начинающееся словами: «никаких поа11аэ, это даже не подлежит обсуждениюь, Понятно, что после этого сообщество пользователей С и С++ без особой охоты возвращалось к проблеме псевдонимов.
Но вопрос был очень важен для пользователей С на платформе Сгау, поэтому Майк Холли (Мгхе Нойу) из компании Сгау, в конце концов, представил улучшенное предложение по этой проблеме группе по численным расширениям С (ХСЕО) и комитету по С++. Идея заключалась в том, чтобы дать программисту возможность декларировать отсутствие у указателя псевдонимов, объявив его с ключевым словом гезггзсгл Примеры предлагавшихся расширений ~иффффффЩ пользователь об этом может и не знать, а сам компилятор убедиться в этом не способен. Из-за интенсивного использования указателей и ссылок в С++ возможно появление болыпого числа ошибок, и опыт Рог(гап тут ничего не доказывает; ш альтернативы предложению недостаточно исследованы.
Во многих слугаях можно было бы провести начальную проверку на перекрытие и при его отсутствии выбрать оптимизированный вариант алгоритма. В других случаях стоит обратиться к специализированным математическим библиотекам (например, В1 Л8), которые имеют специальную поддержку для векторных операпий. Еше предстоит изучить многообещающие альтернативные способы оптимизации. Например, глобальная оптимизация относительно небольших и легко распознаваемых участков кода, где встречаются операции с векторами и матрицами, представляется вполне реализуемой в компиляторах С++ для высокопроизводительных компьютеров; з раси~прение зависит от архитектуры. Высокопроизводительные численные расчеты — это специальная область со своими методами, зачастую предполагаюшая наличие особой аппаратуры.
Поэтому лучше ввести нестандартное архитектурно-зависимое расширение или прагму. Если же такого рода оптимизация окажется полезной и более широкому кругу пользователей, то к рассмотрению этого расширения можно будет вернуться. Принятое решение еще раз подтверждает, что С++ поддерживает абстрагирование за счет об1пих механизмов, а не специализированные приложения путем реализации специальных средств, Конечно, я хотел бы помочь людям, занимающимся численными расчетами, но как? Идти по стопам рог(гав в реализации классических векторных и матричных алгоритмов — это далеко не всегда самый лучший путь.
Было бы хорошо, если бы любую расчетную программу можно было написать на С++ без потери эффективности, но если не удастся достичь этого, пе принося в жертву систему контроля типов С++, то, видимо, стоит обратиться к Готы гап, ассемблеру или архитектурно-зависимым расширениям.
б.5.3. Наборы символов Язык С ориентирован на американский вариант международного 7-битного набора символов 180 646-1983, называемого также АБСП (А)ч813.4-1968). Это порождает две проблемы: о код АБСП содержит некоторые знаки препинания и специальные символы, например 1 или (, которых нет во многих национальных наборах символов; о В коде АБСП отсутствуют символы типа 8 и ж, которых нет в английском алфавите, 6.5.3.1. Ограниченные наборы символов В коде ЛБСП (АХ813.4-1968) специальные символы [, 1, (, ), ~ и ~ занимают позиции, которые по стандарту!80 отведены под буквы. В больц~инстве европейских национальных наборов символов 180-646 эти позиции заняты буквами, БИИИИИИ61 Стандартизация гпт пахп(ьпх ахдс, спас* ахдч(]) ( 11 (атдс<1 (( *ахдч(1] == ')О') хетитп О) рх1птг("Не11о, Ъа)п",ахдч[1])7 На стандартном датском терминале или принтере она будет выглядеть так: тпт па1п(1пт ахдс, спах* ахдчЛЯ ) (ахдс<1 ае *ахдчя1Я == 'ВО') хетихп 0; рх]птт('Не11о, Ваап",ахдчя1Я); а Комитет АХ81 С одобрил частичное решение проблемы, определив набор триграфов, с помощью которых можно вводить символы национальных алфавитов: ( 1 ] ) ??< 7?/ ??) ?7> 2?' ??( ??- О ( 27= ?7( Возможно, для обмена программами это и имеет смысл, но удобочитаемость записи остается на прежнем уровне: гпх еаьп(1пх ахдс, спас* атдч??(??)) 7?< 11 (атдс<1 ?71??! *ахдч??(1??) == '?7/О') хетихп 0; рхтптт("Не11о, Ъа??/и",ахдч??(1??)); ао) Разумеется, решить эту проблему можно, купив оборудование, которое поддерживает как национальный язык, так и символы, необходимые С и С++.
К сожалению, иногда это оказывается невозможным, да и вообще замена оборудования — процесс медленный. Чтобы помочь программистам, работающим на старом оборудовании, а значит, и продвигать С++, комитет по стандартизации решил предоставить более удобную нотацию. которых нет в английском алфавите.
Например, в датском наборе символов иа этих местах находятся гласные )а, Я, а, Я, о и 8, без которых невозможно написать сколько-нибудь осмысленный датский текст. Это ставит датских программистов перед неприятным выбором: либо приобретать компьютеры, на которых есть полный 8-битный набор символов (например, 180-8859/1/2), либо не использовать три гласные буквы своего родного языка, либо не программировать на С++. Люди, говорящие на немецком, французском, испанском, итальянском и других языках, сталкиваются с той же проблемой.
Кстати, данное недоразумение стало серьезным препятствием на пути признания С в Европе, особенно в коммерческих приложениях (к примеру, банковских системах), поскольку 7-битные национальные наборы символов во многих странах используются повсеместно. Рассмотрим, например, безобидную, на первый взгляд, программу на АХ81 С и С++: Примеры предлагавшихся расширений:;$$фффЯЯЩ Показанные в табл. 6.1 слова и лиграфы являются эквивалентами операторов, солсржап(их символы национальных алфавитов.
Таблица б. 1 Ключевые слова Дигрвфы апд апд ед Ьиапд Ыгог сопр1 пог ог ед хог хог ед пог ед Я бы прелпочел ЪЪ |(ля (( и <> лля ! =, но а | и под ес( — лучший компромисс, на котором сошлись комитеты по С и С~-~. В этих обозначениях наш пример выглядит следующим образом: гпг та1п(дпг агдс, спаг* агде<: :>( <Ъ (агдс<1 ог *агдп<:1:>=='>>|О'( геспгл О; рг1пгг("не11о, «а>>!и", агдп<:1;>); «> Замечу, что триграфы все-таки необхолимы лля вставки таких «отсутствующих» символов, как 1, в строки и символьные константы.
Ввелепие лиграфов и новых ключевых слов вызвало споры. Многие пользователи — в основном, англоговоряшис и имеющие большой опыт работы с С вЂ” нс видели причин усложнять и портить С++ ради тех, кто «не хочет купить приличное оборулование». Мне такая позиция близка, поскольку лиграфы и триграфы— не верх изя(цества, а новые ключевые слова — всегда источник несовместимости. С другой стороны, мне прихолилось работать на оборуловании, которое не поллерживало мой ролной язык, и я видел, как люли отказывались от С в пользу «языка, в котором нет этих лурацких символов». Также я припоминаю отчет представителя 1ВМ о том, что отсутствие символа .' в кодировке ЕВС01С, применяемой на мейнфреймах 1ВМ, — причина частых жалоб.
Интересно отмстить, что даже в тех случаях, котла расширенные наборы символов имеются, системные администраторы иногла запрещают их употребление. Думается, что на переходный период, который может продлиться лет десять, лиграфы и триграфы — это меньшее из зол. Надеюсь, это поможет С++ завоевать НИИИИИ16 Стандартизация те области, в ко~орые так и не смог проникнуть С, и поддержать программистов, которые раисе пс вхолили в сообщество С и С-»-».
б.5.3.2. Расширенные наборы символов Поддержка ограниченных наборов символов в языке С++ — всего л иш ь взгляд в прошлое. Более интересная и трупная задача — поддержка расширенных наборов символом, в которых число символов больше, чем в кодс ЛАСИ. Злссь есть два важных вопроса: сз как поддержать манипуляции с расширенными наборами символов? ? как позволить употребление расширенных наборов в исхолных текстах программ па Сч-'? Первую проблему комитет по стандартизации С решил путем определения типа»»сйаг г. лля представления многобайтных символов. Кроме того, был введен тнп»»с?зас с [ [ для многобайтных строк, а функщщ семейства рг"' пс = расширили для ввода/вывода тина»»с?тат с.
В С++ мспаг с стал настоящим типом (а ие просто синонимом для другого типа, определенного в С с помощью суреае?), стандартный класс»»эсг?пс был введен лля строк символов тниа »»с?заг с, и эти типы были полдержаны срслствами потокового ввода/вывода. Таким образом, поддержан только один тип» широких символов».
Если программисту нужно болыне типов, скажем, лля японских символов, строк японских символов, символов иврита или составленных из них строк, то существует, ио крайней мсрс, два альтернативных подхола. Можно отобразить такие символы в общепринятом, лостаточно большом наборе (скажем, ()и[соде) и написать код, работающий с этим набором, а нс с»»с[тат с. Допустимо также определить классы для каждого вила символов и строк, например ?с?тат, ~эсг?пс, Нс?заг и нэсг?пс, и добиться, чтобы кажлый из них правильно работал. Такие классы должны генерироваться из общего шаблона.