Руководство по Ada (Ada 2022)
13.5.1 Определения представления записей
Определение record_representation_clause задаёт представление в памяти записей и расширений записей, то есть порядок, положение и размер компонентов (включая дискриминанты, если таковые имеются).
Синтаксис
record_representation_clause ::=
for first_subtype_local_name use
record [mod_clause]
{component_clause}
end record [local_name];
for first_subtype_local_name use
record [mod_clause]
{component_clause}
end record [local_name];
Если имя local_name появляется в конце определения record_representation_clause, оно должно повторять first_subtype_local_name.
Правила разрешения имён
Правила допустимости
Имя first_subtype_local_name определения record_representation_clause должно обозначать конкретный тип записи или тип расширения записи.
Если имя component_local_name является direct_name, то имя local_name должно обозначать компонент типа. Для расширения записи компонент не должен быть унаследованным и не должен быть дискриминантом, соответствующим дискриминанту родительского типа. Если у component_local_name есть attribute_designator, direct_name имени local_name должно обозначать либо объявление типа, либо компонент типа, а attribute_designator должно обозначать компонент типа, определяемый реализацией.
Значения position, first_bit и last_bit должны быть статическими выражениями. Значения position и first_bit должны быть неотрицательными. Значение last_bit должно быть не меньше first_bit – 1.
Если для типа применяется порядок битов по умолчанию, то:
- значение last_bit должно быть меньше размера наибольшего машинного скаляра; или
- значение first_bit должно быть нулём, а значение last_bit + 1 должно быть кратным System.Storage_Unit.
Для каждого компонента типа, включая каждый дискриминант, допускается не более одного component_clause (component_clause могут быть указаны для некоторых, всех или ни одного из компонентов). Места хранения в component_list не должны перекрываться, если они не для компонентов в различных variant тех же variant_part.
Имя, обозначающее компонент типа, не допускается в record_representation_clause для типа, за исключением component_local_name component_clause.
Статические семантики
Определение record_representation_clause (без mod_clause) задаёт расположение.
Если для типа применяется порядок битов по умолчанию, то position, first_bit и last_bit каждого component_clause непосредственно задают положение и размер соответствующего компонента.
Если для типа применяется нестандартный порядок битов, то расположение определяется следующим образом:
- для component_clauseов, где значение last_bit больше или равно размеру наибольшего машинного скаляра, непосредственно задаются положение и размер соответствующего компонента;
- для других component_clauseов, все компоненты с одинаковым значением position рассматриваются как часть одного машинного скаляра, расположенного по этому position; этот машинный скаляр имеет размер, который является наименьшим размером машинного скаляра, большим чем наибольшее значение last_bit для всех component_clauseов в этом position; first_bit и last_bit каждого component_clause затем интерпретируются как битовые смещения в этом машинном скаляре.
Определение record_representation_clause для расширения записи не переопределяет расположение родительской части; если расположение было указано для родительского типа, оно унаследовано расширением записи.
Разрешения реализации
Реализация может генерировать компоненты, определённые реализацией (например, один, содержащий смещение другого компонента). Реализация может генерировать имена, обозначающие такие компоненты, определённые реализацией; такие имена должны быть именами attribute_reference, определяемыми реализацией. Реализация может разрешить использование таких имён, определённых реализацией, в определениях record_representation_clause. Реализация может ограничивать такие component_clauses любым способом.
Если определение record_representation_clause дано для немеченых производных типов, атрибуты места хранения для всех компонентов производного типа могут отличаться от соответствующих компонентов родительского типа, даже для компонентов, место хранения которых не указано явно в record_representation_clause.
Рекомендации для реализации
Рекомендуемый уровень поддержки для record_representation_clauses:
- Реализация должна поддерживать машинные скаляры, соответствующие всем форматам целых чисел, чисел с плавающей точкой и адресов, поддерживаемым машиной.
- Реализация должна поддерживать места хранения, которые могут быть извлечены с помощью последовательности команд загрузки, маскирования, сдвига машинного кода и устанавливаться с помощью последовательности команд загрузки, сдвига, маскирования, сохранения, учитывая доступные машинные инструкции и модель выполнения.
- Место хранения должно поддерживаться, если его размер равен размеру подтипа компонента, и оно начинается и заканчивается на границе, которая подчиняется выравниванию подтипа компонента.
- Для компонента с подтипом, размер которого меньше размера слова, должно поддерживаться любое место хранения, которое не пересекает выровненную границу слова.
- Реализация может зарезервировать место хранения для поля тега помеченного типа и запретить другим компонентам перекрывать это место.
- Реализация не обязана поддерживать component_clause для компонента части расширения, если место хранения не следует за местами хранения всех компонентов родительского типа, независимо от того, были ли эти места хранения указаны.
ПРИМЕЧАНИЕ Если для компонента не указан component_clause, то выбор места хранения компонента оставляется на усмотрение реализации. Если для всех компонентов указаны component_clauses, то record_representation_clause полностью определяет представление типа и будет точно соблюдаться реализацией.
Примеры
Пример указания макета типа записи:
Word : constant := 4; -- элемент хранения — байт, 4 байта на слово
type State is (A,M,W,P);
type Mode is (Fix, Dec, Exp, Signif);
type Mode is (Fix, Dec, Exp, Signif);
type Byte_Mask is array (0..7) of Boolean with Component_Size => 1;
type State_Mask is array (State) of Boolean with Component_Size => 1;
type Mode_Mask is array (Mode) of Boolean with Component_Size => 1;
type State_Mask is array (State) of Boolean with Component_Size => 1;
type Mode_Mask is array (Mode) of Boolean with Component_Size => 1;
type Program_Status_Word is
record
System_Mask : Byte_Mask;
Protection_Key : Integer range 0 .. 3;
Machine_State : State_Mask;
Interrupt_Cause : Interruption_Code;
Ilc : Integer range 0 .. 3;
Cc : Integer range 0 .. 3;
Program_Mask : Mode_Mask;
Inst_Address : Address;
end record;
record
System_Mask : Byte_Mask;
Protection_Key : Integer range 0 .. 3;
Machine_State : State_Mask;
Interrupt_Cause : Interruption_Code;
Ilc : Integer range 0 .. 3;
Cc : Integer range 0 .. 3;
Program_Mask : Mode_Mask;
Inst_Address : Address;
end record;
for Program_Status_Word use
record
System_Mask at 0*Word range 0 .. 7;
Protection_Key at 0*Word range 10 .. 11; -- биты 8,9 не используются
Machine_State at 0*Word range 12 .. 15;
Interrupt_Cause at 0*Word range 16 .. 31;
Ilc at 1*Word range 0 .. 1; -- второе слово
Cc at 1*Word range 2 .. 3;
Program_Mask at 1*Word range 4 .. 7;
Inst_Address at 1*Word range 8 .. 31;
end record;
record
System_Mask at 0*Word range 0 .. 7;
Protection_Key at 0*Word range 10 .. 11; -- биты 8,9 не используются
Machine_State at 0*Word range 12 .. 15;
Interrupt_Cause at 0*Word range 16 .. 31;
Ilc at 1*Word range 0 .. 1; -- второе слово
Cc at 1*Word range 2 .. 3;
Program_Mask at 1*Word range 4 .. 7;
Inst_Address at 1*Word range 8 .. 31;
end record;
for Program_Status_Word'Size use 8*System.Storage_Unit;
for Program_Status_Word'Alignment use 8;
for Program_Status_Word'Alignment use 8;
Пункт record_representation_clause определяет макет записи. Пункт Size гарантирует, что (по крайней мере) восемь элементов хранения используются для объектов типа. Пункт Alignment гарантирует, что адреса алиасов, импортированных или экспортированных объектов типа будут кратны восьми.