Справочник по Ada 95
Введение
Это Справочник по Ada.
Другие доступные документы по Ada:
- Обоснование языка программирования Ada — издание 1995 года, которое даёт введение в новые возможности Ada и объясняет причины их внедрения. Программисты должны прочитать его в первую очередь.
- Этот абзац был удалён.
- Аннотированный справочник по Ada (AARM). AARM содержит весь текст RM95 плюс различные аннотации. Он предназначен в первую очередь для авторов компиляторов, разработчиков тестов валидации и других, кто хочет изучить подробности. Аннотации включают подробное обоснование отдельных правил и объяснения некоторых более сложных взаимодействий между правилами.
Цели разработки
Ada изначально разрабатывался с тремя основными целями: надёжность и сопровождаемость программ, программирование как человеческая деятельность и эффективность. Эта переработка языка была разработана для обеспечения большей гибкости и расширяемости, дополнительного контроля над управлением памятью и синхронизацией, и стандартизированных пакетов, ориентированных на поддержку важных областей применения, сохраняя при этом первоначальное внимание к надёжности, сопровождаемости и эффективности.
Необходимость языков, которые способствуют надёжности и упрощают сопровождаемость, хорошо известна. Поэтому основной упор был сделан на удобочитаемости программы, а не на лёгкости написания. Например, правила языка требуют явного объявления переменных и указания их типа. Поскольку тип переменной неизменен, компиляторы могут гарантировать, что операции с переменными совместимы с свойствами объектов данного типа. Кроме того, были избегнуты подверженные ошибкам обозначения, а синтаксис языка избегает использования кодированных форм в пользу более английских конструкций. Наконец, язык поддерживает раздельный компиляцию программных модулей таким образом, который облегчает разработку и сопровождение программ, а также обеспечивает тот же уровень проверки между модулями, что и внутри модуля.
При разработке также уделялось внимание программисту-человеку. Прежде всего, была сделана попытка сохранить относительно небольшое количество основных концепций, интегрированных согласованным и систематическим способом, избегая при этом ловушек чрезмерной сложностей. Дизайн особенно стремится предоставить конструкции языка, интуитивно соответствующие обычным ожиданиям пользователей.
Как и во многих других человеческих видах деятельности, разработка программного обеспечения становится всё более децентрализованной и распределённой. Следовательно, возможность сборки программы из независимо созданных программных компонентов остаётся центральной идеей при проектировании. Понятия пакетов, частных типов и обобщенных модулей напрямую связаны с этой идеей, которая имеет последствия во многих других аспектах языка. Сопряжённая проблема – сопровождение программ для соответствия меняющимся требованиям; расширение типа и иерархическая библиотека позволяют изменять программу, сводя к минимуму нарушения существующих протестированных и надёжных компонентов.
Ни один язык не может избежать проблемы эффективности. Языки, которые требуют чрезмерно сложных компиляторов или приводят к неэффективному использованию памяти или времени выполнения, навязывают эти недостатки всем машинам и всем программам. Каждая конструкция языка была проанализирована с учётом современных методик реализации. Любая предлагаемая конструкция, реализация которой была неясна или требовала чрезмерных ресурсов машины, была отклонена.
Резюме языка
Программа Ada состоит из одного или нескольких программных модулей. Программные модули могут быть подпрограммами (которые определяют исполняемые алгоритмы), пакетами (которые определяют коллекции сущностей), модулями задач (которые определяют параллельные вычисления), защищенными модулями (которые определяют операции для согласованного обмена данными между задачами) или обобщенными модулями (которые определяют параметризованные формы пакетов и подпрограмм). Каждый программный модуль обычно состоит из двух частей: спецификации, содержащей информацию, которая должна быть видна другим модулям, и тела, содержащего детали реализации, которые не обязательно должны быть видны другим модулям. Большинство программных модулей могут быть скомпилированы раздельно.
Это различие между спецификацией и телом, а также возможность раздельно компилировать модули, позволяет проектировать, писать и тестировать программу как набор в значительной степени независимых программных компонентов.
Программа Ada обычно использует библиотеку программных модулей общего назначения. Язык предоставляет средства, с помощью которых отдельные организации могут создавать свои собственные библиотеки. Все библиотеки структурированы иерархически; это позволяет логически разложить подсистему на отдельные компоненты. Текст раздельно скомпилированного программного модуля должен указывать на необходимые библиотечные модули.
Программные модули
Подпрограмма является основной единицей для выражения алгоритма. Существует два типа подпрограмм: процедуры и функции. Процедура – это средство вызова последовательности действий. Например, она может считывать данные, обновлять переменные или генерировать вывод. Она может иметь параметры для обеспечения контролируемого способа передачи информации между процедурой и точкой вызова. Функция – это средство вызова вычисления значения. Она похожа на процедуру, но, кроме того, возвращает результат.
Пакет является основной единицей для определения коллекции логически связанных сущностей. Например, пакет можно использовать для определения набора деклараций типов и связанных операций. Части пакета могут быть скрыты от пользователя, что позволяет получить доступ только к логическим свойствам, выраженным в спецификации пакета.
Модули подпрограмм и пакетов могут быть скомпилированы раздельно и организованы в иерархии родительских и дочерних модулей, обеспечивая точный контроль над видимостью логических свойств и их детальной реализацией.
Модуль задачи является основной единицей для определения задачи, последовательность действий которой может выполняться параллельно с действиями других задач. Такие задачи могут быть реализованы на многопроцессорных системах, многопроцессорных машинах или с перекрывающимся выполнением на одном процессоре. Модуль задачи может определять либо одну исполняемую задачу, либо тип задачи, позволяющий создать любое количество подобных задач.
Защищённый модуль – это базовая единица для определения защищённых операций для согласованного использования данных, общих между задачами. Простая взаимная исключаемость обеспечивается автоматически, и могут быть определены более сложные протоколы совместного использования. Защищённая операция может быть либо подпрограммой, либо входом. Защищённый вход определяет булево выражение (барьер входа), которое должно быть истинным, прежде чем выполняется тело входа. Защищённый модуль может определить один защищённый объект или защищённый тип, позволяющий создать несколько подобных объектов.
Декларации и операторы
Тело программного модуля обычно содержит две части: декларативную часть, которая определяет логические сущности, используемые в программном модуле, и последовательность операторов, которые определяют выполнение программного модуля.
Декларативная часть связывает имена с декларируемыми сущностями. Например, имя может обозначать тип, константу, переменную или исключение. Декларативная часть также вводит имена и параметры других вложенных подпрограмм, пакетов, модулей задач, защищённых модулей и обобщённых модулей, которые будут использоваться в программном модуле.
Последовательность операторов описывает последовательность действий, которые должны выполняться. Операторы выполняются последовательно (если передача управления не вызывает продолжения выполнения с другого места).
Оператор присваивания изменяет значение переменной. Вызов процедуры вызывает выполнение процедуры после сопоставления всех фактических параметров, предоставленных при вызове, с соответствующими формальными параметрами.
Операторы выбора и if позволяют выбрать вложенную последовательность операторов на основе значения выражения или на основе значения условия.
Оператор цикла предоставляет основную итерационную механику в языке. Оператор цикла указывает, что последовательность операторов должна выполняться повторно в соответствии с указанным режимом итерации или пока не будет встречен оператор выхода.
Оператор блока содержит последовательность операторов, предваряемую объявлением локальных сущностей, используемых операторами.
Некоторые операторы связаны с одновременным выполнением. Оператор задержки задерживает выполнение задачи на указанное время или до указанного момента. Оператор вызова входа записывается как оператор вызова процедуры; он запрашивает операцию в задаче или защищённом объекте, блокируя вызывающий объект до тех пор, пока операция не будет выполнена. Вызываемая задача может принять вызов входа, выполнив соответствующий оператор приёма, который указывает действия, которые должны быть выполнены в рамках взаимодействия с вызывающей задачей. Вызов входа защищённого объекта обрабатывается, когда соответствующее выражение барьера входа оценивается как истинное, после чего выполняется тело входа. Оператор переочередивания позволяет предоставить услугу в виде ряда взаимосвязанных действий с управлением приоритетами. Один из вариантов оператора выбора позволяет выборочно ожидать одного из нескольких альтернативных взаимодействий. Другие варианты оператора выбора позволяют условные или временные вызовы входа и асинхронную передачу управления в ответ на какое-либо событие запуска.
Выполнение программного модуля может столкнуться с ошибочными ситуациями, в которых нормальное выполнение программы не может быть продолжено. Например, арифметическое вычисление может превысить максимальное разрешённое значение числа, или может быть предпринята попытка доступа к элементу массива с использованием неправильного индекса. Для решения таких проблем операторы программного модуля могут быть текстово дополнены обработчиками исключений, которые указывают действия, которые должны быть выполнены, когда возникает ошибка. Исключение может быть поднято явно оператором raise.
Типы данных
Каждый объект в языке имеет тип, который характеризует множество значений и множество применимых операций. Основные классы типов — это элементарные типы (включающие перечисления, числовые и типы доступа) и составные типы (включающие массивы и типы записей).
Тип перечисления определяет упорядоченное множество различных литералов перечисления, например, список состояний или алфавит символов. Типы перечислений Boolean, Character и Wide_Character заданы заранее.
Числовые типы предоставляют средства для выполнения точных или приближенных числовых вычислений. Точные вычисления используют целочисленные типы, которые обозначают множества последовательных целых чисел. Приближенные вычисления используют либо типы с фиксированной точкой, с абсолютными границами ошибки, либо типы с плавающей точкой, с относительными границами ошибки. Числовые типы Integer, Float и Duration заданы заранее.
Составные типы позволяют определять структурированные объекты с связанными компонентами. Составные типы в языке включают массивы и записи. Массив — это объект с индексированными компонентами одного и того же типа. Запись — это объект с именованными компонентами, которые могут иметь разные типы. Задачи и защищенные типы также являются формами составных типов. Типы массивов String и Wide_String заданы заранее.
Типы записей, задач и защищенных типов могут иметь специальные компоненты, называемые дискриминантами, которые параметризуют тип. Внутри типа записи могут быть определены структуры записей с вариантами, которые зависят от значений дискриминантов.
Типы доступа позволяют создавать связанные структуры данных. Значение типа доступа представляет собой ссылку на объект, объявленный как алиас, или на объект, созданный в результате вычисления выделения памяти. Несколько переменных типа доступа могут обозначать один и тот же объект, а компоненты одного объекта могут обозначать один и тот же или другие объекты. Как элементы в таких связанных структурах данных, так и их взаимосвязь с другими элементами могут изменяться во время выполнения программы. Типы доступа также позволяют хранить ссылки на подпрограммы, передавать их в качестве параметров и, в конечном итоге, разыменовывать их в рамках непрямого вызова.
Секретные типы допускают ограниченные представления типа. Секретный тип может быть определен в пакете таким образом, чтобы только логически необходимые свойства были видимы пользователям типа. Полные структурные детали, которые внешне не имеют значения, затем доступны только внутри пакета и любых дочерних модулей.
Из любого типа можно определить новый тип путем вывода. Тип вместе с его производными (как прямыми, так и косвенными) образует класс производных. Можно определять операции для всего класса, принимающие в качестве параметра операнд любого типа в классе производных. Для типов записей и секретных типов производные могут быть расширениями родительского типа. Типы, которые поддерживают эти возможности объектно-ориентированного программирования — операции для всего класса и расширение типов — должны быть помечены, чтобы тип операнда в классе производных можно было идентифицировать во время выполнения. Когда операция помеченного типа применяется к операнду, чье конкретный тип неизвестен до момента выполнения, выполняется неявное распределение, основанное на метке операнда.
Понятие типа дополняется понятием подтипа, позволяющим пользователю ограничивать множество допустимых значений типа. Подтипы могут использоваться для определения поддиапазонов скалярных типов, массивов с ограниченным набором значений индексов, а также записей и секретных типов с определенными значениями дискриминантов.
Другие возможности
Представления строк могут использоваться для указания отображения между типами и особенностями базовой машины. Например, пользователь может указать, что объекты данного типа должны быть представлены с определенным количеством бит или что компоненты записи должны быть представлены с определенной структурой хранения. Другие возможности позволяют контролировать использование низкоуровневых, непереносимых или зависящих от реализации аспектов, включая непосредственное вставление машинного кода.
Предварительно определенная среда языка предоставляет возможности ввода-вывода и другие возможности (такие как обработка строк и генерация случайных чисел) с помощью стандартных пакетов библиотек. Ввод-вывод поддерживается для значений как пользовательских, так и предварительно определенных типов. Также предоставляются стандартные способы представления значений в виде отображения.
Другие стандартные пакеты библиотек определены в приложениях стандарта для поддержки систем со специализированными требованиями.
Наконец, язык предоставляет мощный механизм параметризации программных модулей, называемый обобщенными программными модулями. Обобщенные параметры могут быть типами и подпрограммами (а также объектами и пакетами), что позволяет определять общие алгоритмы и структуры данных, применимые ко всем типам данного класса.
Изменения в языке
Этот международный стандарт заменяет первое издание 1987 года. В этом издании были внесены следующие основные изменения в язык:
- Поддержка стандартных 8-битных и 16-битных наборов символов. См. раздел 2, 3.5.2, 3.6.3, A.1, A.3 и A.4.
- Объектно-ориентированное программирование с полиморфизмом во время выполнения. См. обсуждения классов, производных типов, помеченных типов, расширений записей и расширений секретных типов в разделах 3.4, 3.9 и 7.3. См. также новые формы обобщенных формальных параметров, разрешенные в 12.5.1, «Формальные секретные и производные типы» и 12.7, «Формальные пакеты».
- Типы доступа были расширены, чтобы разрешить значению доступа обозначать подпрограмму или объект, объявленный объявлением объекта (а не только объект, выделенный в куче). См. 3.10.
- Эффективная синхронизация данных обеспечивается с помощью защищенных типов. См. раздел 9.
- Модули библиотеки могут быть организованы в иерархии родительских и дочерних модулей. См. раздел 10.
- Была добавлена дополнительная поддержка для взаимодействия с другими языками. См. Приложение B.
- Добавлены приложения для специализированных потребностей, чтобы предоставить конкретную поддержку для определенных областей применения:
Благодарности
Этот международный стандарт был подготовлен командой Ada 9X Mapping/Revision при Intermetrics, Inc., в состав которой вошли: W. Carlson, менеджер проектов; T. Taft, технический директор; J. Barnes (консультант); B. Brosgol (консультант); R. Duff (Oak Tree Software); M. Edwards; C. Garrity; R. Hilliard; O. Pazy (консультант); D. Rosenfeld; L. Shafer; W. White; M. Woodger.
Следующие консультанты проекта Ada 9X внесли вклад в приложения для специализированных потребностей: T. Baker (системы реального времени/программирование систем — SEI, FSU); K. Dritz (численные расчеты — Аргонская национальная лаборатория); A. Gargaro (распределенные системы — Computer Sciences); J. Goodenough (системы реального времени/программирование систем — SEI); J. McHugh (системы защиты — консультант); B. Wichmann (системы для критически важных применений — NPL: Великобритания).
Эта работа регулярно рассматривалась экспертами по Ада 9X и членами группы репортеров Ада 9X (XRG): Э. Плоэдерером, председателем экспертов и XRG (Штутгартский университет: Германия); Б. Бардином (Hughes); Дж. Барнсом (консультант: Великобритания); Б. Бреттом (DEC); Б. Бросголом (консультант); Р. Брукардтом (RR Software); Н. Коэном (IBM); Р. Дьюаром (Нью-Йоркский университет); Г. Дизмукесом (TeleSoft); А. Эвансом (консультант); А. Гаргаро (Computer Sciences); М. Герхардтом (ESL); Дж. Гуднуфом (SEI); С. Хейльбруннером (Зальцбургский университет: Австрия); П. Хильфингером (UC/Беркли); Б. Кёльбергом (CelsiusTech: Швеция); М. Камрадом II (Unisys); Дж. ван Катвайком (Делфтский технологический университет: Нидерланды); В. Кауфманом (Россия); П. Крухтеном (Rational); Р. Ландверром (CCI: Германия); К. Лестером (Портсмутский политехнический институт: Великобритания); Л. Мёнссоном (TELIA Research: Швеция); С. Мичеллом (Multiprocessor Toolsmiths: Канада); М. Миллсом (ВВС США); Д. Погге (ВМС США); К. Пауэром (Boeing); О. Рубине (Verdix: Франция); А. Штромейером (Федеральный технологический институт Швейцарии: Швейцария); У. Тейлором (консультант: Великобритания); Дж. Токаром (Tartan); Э. Василеску (Grumman); Дж. Владик (Prospeks s.r.o.: Чешская Республика); С. Ван Влиерберге (OFFIS: Бельгия).
Другие ценные отзывы, повлиявшие на процесс ревизии, были предоставлены командой Ада 9X по точности языка (Odyssey Research Associates), командами пользователей/внедренцев Ада 9X (AETECH, Tartan, TeleSoft), группой анализа реализации Ада 9X (Нью-Йоркский университет) и широкой общественностью сообщества Ада.
Особая благодарность Р. Матису, руководителю рабочей группы ISO/IEC JTC1/SC22 9.
Проект Ada 9X был спонсирован Объединенным программным офисом Ada. Кристин М. Андерсон в Лаборатории ВВС Филипса (Kirtland AFB, NM) была руководителем проекта.
Изменения
Международный стандарт идентичен этой версии Справочного руководства, за исключением:
- Этот список изменений не включен в Международный стандарт.
- Страница «Благодарности» не включена в Международный стандарт.
- Текст в заголовках и подзаголовках на каждой странице немного отличается в Международном стандарте.
- Заглавные страницы отличаются в Международном стандарте.
- Этот документ отформатирован для бумаги размером 8,5 на 11 дюймов, в то время как Международный стандарт отформатирован для бумаги А4 (210 на 297 мм); следовательно, разрывы страниц расположены в разных местах.
- Раздел «Предисловие к данной версии Справочного руководства по Ада» не включен в Международный стандарт.