Руководство по Ada (Ada 2022)
11.5 Отключение проверок
Директивы проверки дают инструкции реализации по обработке определённых языком проверок. Директива Suppress разрешает реализации пропускать определённые проверки, заданные языком, а директива Unsuppress отменяет разрешение пропускать проверки.
Проверка, определённая языком (или просто «проверка») — это одна из ситуаций, определённых в данном документе, которая требует проверки во время выполнения для определения, является ли некоторое условие истинным. Проверка не проходит, когда проверяемое условие ложно, вызывая поднятие исключения.
Синтаксис
Формы директив проверки следующие:
pragma Suppress(идентификатор);
pragma Unsuppress(идентификатор);
Директива проверки допускается только непосредственно внутри раздела_объявлений, непосредственно внутри спецификации_пакета или в качестве конфигурационной директивы.
Правила легитимности
Идентификатор идентификатор должен быть именем проверки.
Этот абзац был удалён.
Статическая семантика
Директива проверки применяется к указанной проверке в определённом регионе и применяется ко всем сущностям в этом регионе. Директива проверки, заданная в разделе_объявлений или непосредственно внутри спецификации_пакета, применяется от места директивы pragma до конца самого внутреннего окружающего раздела объявлений. Регион для директивы проверки, заданной как конфигурационная директива, является разделом объявлений для всего модуля компиляции (или модулей), на который она применяется.
Если директива проверки применяется к инстанцированию_генератора, то директива проверки также применяется ко всему экземпляру.
Директива pragma Suppress разрешает реализации пропускать указанную проверку (или все проверки в случае All_Checks) для любых сущностей, на которые она распространяется. Если разрешение на отключение проверки получено, говорят, что проверка отключена.
Директива pragma Unsuppress отменяет разрешение пропускать указанную проверку (или все проверки в случае All_Checks), предоставленное любой директивой Suppress, которая применяется в момент директивы Unsuppress. Разрешение отменяется для региона, на который распространяется директива Unsuppress. Если такого разрешения нет в момент директивы Unsuppress, то директива не оказывает никакого влияния. Позже директива Suppress может возобновить разрешение.
Ниже приведены проверки, определённые языком:
- Следующие проверки соответствуют ситуациям, в которых исключение Constraint_Error возникает при неудаче проверки, определённой языком.
Access_Check
При оценке разыменования (явного или неявного) проверяется, что значение имени не равно null. При преобразовании в подтип, исключающий null, проверяется, что преобразованное значение не равно null.
Discriminant_Check
Проверяется, что дискриминанты составного значения имеют значения, налагаемые ограничением дискриминанты. Кроме того, при обращении к записи, проверяется, что она существует для текущих значений дискриминанты.
Division_Check
Проверяется, что второй операнд не равен нулю для операций /, rem и mod.
Index_Check
Проверяется, что границы массива равны соответствующим границам ограничения индекса. Кроме того, при обращении к компоненту объекта массива для каждой размерности проверяется, что заданное значение индекса принадлежит диапазону, определённому границами объекта массива. Также при обращении к срезу объекта массива проверяется, что заданный дискретный диапазон совместим с диапазоном, определённым границами объекта массива.
Length_Check
Проверяется, что два массива имеют соответствующие компоненты в случае преобразований типов массивов и логических операций для массивов с boolean-компонентами.
Overflow_Check
Проверяется, что скалярное значение находится в базовом диапазоне своего типа в тех случаях, когда реализация выбирает поднятие исключения вместо возвращения правильного математического результата.
Range_Check
Проверяется, что скалярное значение удовлетворяет ограничению диапазона. Также для разработки указанного_типа проверяется, что ограничение (если оно присутствует) совместимо с типом, обозначаемым именем_типа. Также для агрегата проверяется, что значение индекса или дискриминанты принадлежит соответствующему типу. Также проверяется, что при результате операции, дающем массив, значение каждого компонента принадлежит типу компонента. Также для атрибутов Value, Wide_Value и Wide_Wide_Value проверяется, что данная строка имеет соответствующий синтаксис и значение для базового подтипа префикса префикс ссылки на атрибут ссылка_на_атрибут.
Tag_Check
Проверяется, что теги операндов в вызове диспетчеризации все равны. Проверка правильного тега при преобразованиях типов с тегом, для оператора_присваивания и при возвращении помеченного ограниченного объекта из функции.
- Следующие проверки соответствуют ситуациям, в которых исключение Program_Error возникает при неудаче проверки, определённой языком.
Accessibility_Check
Проверка уровня доступности сущности или вида.
Allocation_Check
Для аллокатоpa проверяется, что мастер любых задач, которые должны быть созданы аллокатором, еще не завершен или некоторые зависимые еще не завершены, и что завершение коллекции еще не началось.
Elaboration_Check
При вызове подпрограммы или защищенного входа, активации задачи или разработке экземпляра генератора проверяется, что тело соответствующего модуля уже разработано.
Program_Error_Check
Другие проверки, определённые языком, которые вызывают Program_Error: что подтипы с предикатными выражениями не используются для индексирования массива в генераторном модуле; что максимальное количество фрагментов больше нуля; что значение по умолчанию для параметра out преобразуемо; что нет злоупотребления функциями в генераторе с повсеместным фактическим типом; что нет конфликтующих значений External_Tag; что нет злоупотребления операциями типов с неконтролируемым объединением.
- Следующая проверка соответствует ситуациям, в которых исключение Storage_Error возникает при неудаче проверки, определённой языком.
Storage_Check
Проверка того, что оценка аллокатора не требует больше места, чем доступно для пула памяти. Проверка того, что доступное место для задачи или подпрограммы не превышено.
- Следующая проверка соответствует ситуациям, в которых исключение Tasking_Error возникает при неудаче проверки, определённой языком.
Tasking_Check
Проверка того, что все активированные задачи успешно активировались. Проверка того, что вызываемая задача ещё не завершена.
- Следующие проверки соответствуют ситуациям, в которых исключение Assertion_Error возникает при неудаче проверки, определённой языком. Для языкового модуля U, связанного с одной из этих проверок в списке ниже, проверка относится к выполнению проверок, связанных с аспектами Pre, Static_Predicate и Dynamic_Predicate, связанными с любой сущностью, объявленной в потомке U или в экземпляре генераторного модуля, который является или объявлен в потомке U. Каждая проверка связана с одним или несколькими модулями:
Calendar_Assertion_Check
Календарь.
Characters_Assertion_Check
Символы, Wide_Characters и Wide_Wide_Characters.
Containers_Assertion_Check
END_OF_DOCUMENT_MARKER Контейнеры.
Interfaces_Assertion_Check
Интерфейсы.
IO_Assertion_Check
Sequential_IO, Direct_IO, Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, Storage_IO, Streams.Stream_IO и Directories.
Numerics_Assertion_Check
Числа.
Strings_Assertion_Check
Строки.
System_Assertion_Check
Система.
- Следующая проверка соответствует всем ситуациям, в которых при неудачном выполнении проверки возникает любое предопределенное исключение.
All_Checks
Представляет собой объединение всех проверок; подавление All_Checks подавляет все проверки, кроме тех, которые связаны с утверждениями. Кроме того, реализации разрешено (но не обязательно) вести себя так, как будто pragma Assertion_Policy(Ignore) применяется к любому блоку кода, к которому применяется pragma Suppress(All_Checks).
Ошибочное выполнение
Если заданная проверка была подавлена, и соответствующая ошибка возникает, выполнение программы является ошибочным. Аналогично, если проверка предпосылки была подавлена, а вычисление предпосылки привело бы к возникновению исключения, выполнение является ошибочным.
Разрешения реализации
Реализация имеет право устанавливать ограничения на проверки pragmas, подлежащие только требованию, что pragma Unsuppress должно разрешать любые имена проверок, поддерживаемые pragma Suppress. Реализация имеет право добавлять дополнительные имена проверок с определенными реализацией семантиками. Когда Overflow_Check был подавлен, реализация также может подавить неопределенный подмножество Range_Checks.
Реализация может поддерживать дополнительный параметр в pragma Unsuppress, аналогичный тому, который разрешен для pragma Suppress (см. J.10). Значение такого параметра определяется реализацией.
Рекомендации по реализации
Реализация должна свести к минимуму код, выполняемый для проверок, которые были подавлены.
ПРИМЕЧАНИЕ 1 Нет гарантии, что подавленная проверка фактически удалена; следовательно, pragma Suppress полезна только для повышения эффективности.
ПРИМЕЧАНИЕ 2 Возможно задать как pragma Suppress, так и Unsuppress для одной и той же проверки сразу внутри одного и того же declarative_part. В этом случае последняя заданная pragma определяет, подавлена ли проверка или нет. Аналогично, возможно повторное подавление проверки, которая была снята с подавления, задав pragma Suppress во внутреннем блоке объявления.
Примеры
Примеры подавления и снятия подавления проверок:
pragma Suppress(Index_Check);
pragma Unsuppress(Overflow_Check);
pragma Unsuppress(Overflow_Check);