Справочник по Ada (Ada 2022)
3.3.1 Объявления объектов
Объявление object_declaration объявляет самостоятельный объект с заданным номинальным подтипом и, необязательно, явным начальным значением, заданным выражением инициализации. Для массива, доступа, задачи или защищенного объекта объявление object_declaration может включать определение (анонимного) типа объекта.
Синтаксис
object_declaration ::=
defining_identifier_list : [aliased] [constant] subtype_indication [:= expression]
[aspect_specification];
| defining_identifier_list : [aliased] [constant] access_definition [:= expression]
[aspect_specification];
| defining_identifier_list : [aliased] [constant] array_type_definition [:= expression]
[aspect_specification];
| single_task_declaration
| single_protected_declaration
defining_identifier_list : [aliased] [constant] subtype_indication [:= expression]
[aspect_specification];
| defining_identifier_list : [aliased] [constant] access_definition [:= expression]
[aspect_specification];
| defining_identifier_list : [aliased] [constant] array_type_definition [:= expression]
[aspect_specification];
| single_task_declaration
| single_protected_declaration
Правила разрешения имён
Для объявления object_declaration с выражением expression после составного разделителя := ожидаемый тип для expression — тип объекта. Это expression называется выражением инициализации.
Правила законности
Объявление object_declaration без ключевого слова constant объявляет переменный объект. Если у него есть subtype_indication или array_type_definition, которые определяют неопределённый подтип, то должно быть выражение инициализации.
Статическая семантика
Объявление object_declaration с ключевым словом constant объявляет постоянный объект. Если у него есть выражение инициализации, то это называется полным объявлением константы. В противном случае — отложенным объявлением константы. Правила для отложенных объявлений констант приведены в 7.4. Правила для полных объявлений констант приведены в этом подпункте.
Любое объявление, которое включает defining_identifier_list с более чем одним defining_identifier, эквивалентно ряду объявлений, каждое из которых содержит один defining_identifier из списка, при этом остальная часть текста объявления копируется для каждого объявления в ряду в том же порядке, что и в списке. Остальная часть данного Справочника опирается на это эквивалентность; объяснения даны для объявлений с одним defining_identifier.
subtype_indication, access_definition или полное определение типа в объявлении object_declaration определяют номинальный подтип объекта. Объявление object_declaration объявляет объект типа номинального подтипа.
Компонент объекта называется требующим поздней инициализации, если:
- он имеет значение доступа к дискриминанту, ограниченное выражением, относящимся к объекту; или
- он имеет выражение инициализации, которое включает имя, обозначающее дискриминант доступа; или
- он имеет выражение инициализации, которое включает ссылку на текущий экземпляр типа либо по имени, либо неявно как целевой объект вызова.
Динамическая семантика
Если составной объект, объявленный объявлением object_declaration, имеет неограниченный номинальный подтип, то, если этот подтип неопределён или объект является постоянным, фактический подтип этого объекта ограничен. Ограничение определяется границами или дискриминантами (если таковые имеются) его начального значения; объект называется ограниченным своим начальным значением. Когда объект не ограничен своим начальным значением, фактический и номинальный подтипы объекта совпадают. Если его фактический подтип ограничен, объект называется ограниченным объектом.
Для объявления object_declaration без выражения инициализации любые начальные значения для объекта или его подкомпонентов определяются неявными начальными значениями, определёнными для его номинального подтипа, следующим образом:
- Неявное начальное значение для подтипа доступа — нулевое значение типа доступа.
- Неявное начальное значение для скалярного подтипа, для которого задан аспект Default_Value, — значение этого аспекта, преобразованное в номинальный подтип (что может вызвать Constraint_Error — см. 4.6, «Преобразования типов»);
- Неявное (и единственное) начальное значение для каждого дискриминанта ограниченного дискриминированного подтипа определяется подтипом.
- Для (определённого) составного подтипа неявное начальное значение каждого компонента с default_expression получается путём вычисления этого выражения и преобразования в номинальный подтип компонента (что может вызвать Constraint_Error), если компонент не является дискриминантом ограниченного подтипа (предыдущий случай) или находится в исключённой variant (см. 3.8.1). Для каждого компонента, который не имеет default_expression, если для составного подтипа задан аспект Default_Component_Value, неявное начальное значение — значение этого аспекта, преобразованное в номинальный подтип компонента; в противном случае неявные начальные значения определяются номинальным подтипом компонента.
- Для защищённого или задачного подтипа существует неявный компонент (очередь входа) для каждого входа, при этом его неявное начальное значение — пустая очередь.
Проведение обработки объявления object_declaration осуществляется в следующем порядке:
1.
subtype_indication, access_definition, array_type_definition, single_task_declaration или single_protected_declaration обрабатывается в первую очередь. Это создаёт номинальный подтип (и анонимный тип в последних четырёх случаях).
2.
Если объявление object_declaration включает выражение инициализации, явное начальное значение получается путём вычисления выражения и преобразования его в номинальный подтип (что может вызвать Constraint_Error — см. 4.6).
3.
Объект создаётся, и если нет выражения инициализации, объект инициализируется по умолчанию. При инициализации объекта по умолчанию обрабатываются любые ограничения объекта (см. 3.8), и любые неявные начальные значения для объекта или для его подкомпонентов получаются, как определено номинальным подтипом. Любые начальные значения (явные или неявные) присваиваются объекту или соответствующим подкомпонентам. Как описано в 5.2 и 7.6, могут вызываться процедуры Initialize и Adjust.
Этот абзац был удалён.
Для третьего шага выше, вычисления и присваивания выполняются в произвольном порядке, при соблюдении следующих ограничений:
- Присваивание любой части объекта предшествует вычислению значения, которое должно быть присвоено.
- Вычисление default_expression, включающего имя дискриминанта, предшествует присваиванию этому дискриминанту.
- Вычисление default_expression для любого компонента, зависящего от дискриминанта, предшествует присваиванию этому дискриминанту.
- Присваивания любым компонентам, включая неявные компоненты, не требующие поздней инициализации, предшествуют оценкам начальных значений для любых компонентов, требующих поздней инициализации; если два компонента оба требуют поздней инициализации, то присваивания частям компонента, происходящие ранее в порядке деклараций компонента, предшествуют оценкам начальных значений компонента, происходящего позже.
Для скалярного подтипа не определено неявное начальное значение, если для типа не указан аспект Default_Value. В отсутствие явной инициализации или указания аспекта Default_Value, недавно созданный скалярный объект может иметь значение, не принадлежащее его подтипу (см. 13.9.1 и H.1).
ПРИМЕЧАНИЕ 1 Неявные начальные значения не определены для неопределенного подтипа, потому что, если номинальный подтип объекта является неопределенным, требуется явное начальное значение.
ПРИМЕЧАНИЕ 2 Как указано выше, автономный объект — это объект, объявленный в object_declaration. Аналогичные определения применяются к «автономной константе» и «автономной переменной». Подкомпонент объекта не является автономным объектом, также как и объект, созданный allocator. Объект, объявленный в loop_parameter_specification, iterator_specification, iterated_component_association, chunk_specification, parameter_specification, entry_index_specification, choice_parameter_specification, extended_return_statement или formal_object_declaration с режимом in out не считается автономным объектом.
ПРИМЕЧАНИЕ 3 Тип автономного объекта не может быть абстрактным (см. 3.9.3).
Примеры
Пример объявления нескольких объектов:
-- объявление нескольких объектов
John, Paul : not null Person_Name := new Person(Sex => M); -- см. 3.10.1
-- эквивалентно двум отдельным объявлениям объектов в указанном порядке
John : not null Person_Name := new Person(Sex => M);
Paul : not null Person_Name := new Person(Sex => M);
Paul : not null Person_Name := new Person(Sex => M);
Примеры объявлений переменных:
Count, Sum : Integer;
Size : Integer range 0 .. 10_000 := 0;
Sorted : Boolean := False;
Color_Table : array(1 .. Max) of Color;
Option : Bit_Vector(1 .. 10) := (others => True); -- см. 3.6
Hello : aliased String := "Hi, world.";
θ, φ : Float range -π .. +π;
Size : Integer range 0 .. 10_000 := 0;
Sorted : Boolean := False;
Color_Table : array(1 .. Max) of Color;
Option : Bit_Vector(1 .. 10) := (others => True); -- см. 3.6
Hello : aliased String := "Hi, world.";
θ, φ : Float range -π .. +π;
Примеры объявлений констант:
Limit : constant Integer := 10_000;
Low_Limit : constant Integer := Limit/10;
Tolerance : constant Real := Dispersion(1.15);
A_String : constant String := "A";
Hello_Msg : constant access String := Hello'Access; -- см. 3.10.2
Low_Limit : constant Integer := Limit/10;
Tolerance : constant Real := Dispersion(1.15);
A_String : constant String := "A";
Hello_Msg : constant access String := Hello'Access; -- см. 3.10.2