Я получаю эту ошибку, потому что у меня есть корпус переключателя в типе с условиями и, следовательно, размер определяется только в зависимости от вида?
Нет.Абзац, на который ссылается сообщение об ошибке (RM 13.1 (22)) в LRM, гласит:
Реализация не должна поддерживать элементы представления, содержащие нестатические выражения, за исключением того, что реализация должна поддерживать элемент представления длязаданной сущности, если каждое нестатическое выражение в элементе представления является именем, которое статически обозначает константу, объявленную перед сущностью.
Теперь элемент представления здесь является вызовом Alloc
, поскольку ваш код:
for New_Option use at St_Wa.Alloc(StoragePool => StoragePool,
BitSize => New_Type'Size);
в стиле Ada83 для
for New_Option'Address use St_Wa.Alloc(StoragePool => StoragePool,
BitSize => New_Type'Size);
И поскольку Alloc (...)
является вызовом функции, это не статическое выражение, поскольку статические функции, согласно RM 4.9:
- предопределенный оператор, все параметры и типы результатов которого являются скалярными типами, ни один из которых не является потомком формальных скалярных типов;
- предопределенный оператор конкатенации, тип результата которого является строковым типом;
- литерал перечисления;
- атрибут, определяемый языком, который является функциейЕсли префикс обозначает статический скалярный подтип и если параметры и типы результатов являются скалярными.
Поскольку Alloc
не является ни одним из вышеперечисленных, как утверждает RM 13.1, реализацияне нужно поддерживать его в элементе представления.Однако фактическое сообщение об ошибке говорит нам, что «Alloc» не является чистым , поэтому GNAT сообщает, что оно поддержит это, если Alloc
будет чистым.
Так что один из способов исправить этобыть чистым Alloc
, что означает: Добавить pragma Pure;
в пакет St_Wa
, который содержит Alloc
.Возможность этого зависит от пакета и может потребовать дополнительных изменений.
Если это неосуществимо, RM 13.1 (22) намекает на другой способ: нестатическое выражение должно поддерживаться, если оно обозначает константу, объявленную ранее.лицо.Таким образом, это должно работать:
My_Address : constant System.Address :=
St_Wa.Alloc(StoragePool => StoragePool, BitSize => New_Type'Size);
New_Option : New_Type;
for New_Option use at My_Address;