将一些旧代码移植到较新的CentOs Linux机器上。我使用带有几个标志的linux gnat:
Default_Switches(“ada”)使用(“-fstack-check”,“ - g”,“–gnatVr”,“ - nonato”,“ - nonatE”,“ - logatwmuv”,“ - …
我是否收到此错误,因为我有一个带有条件的类型的开关盒,因此尺寸只取决于种类?
否.LRM中错误消息(RM 13.1(22))引用的段落如下:
实现不需要支持包含非静态表达式的表示项,除非实现应该支持给定实体的表示项,如果表示项中的每个非静态表达式是静态表示在实体之前声明的常量的名称。
现在,这里的表示项是对它的调用 Alloc 既然你的代码:
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 (...)
一个预定义的运算符,其参数和结果类型都是标量类型,它们都不是正式标量类型的后代; 预定义的连接运算符,其结果类型是字符串类型; 枚举字面; 如果前缀表示静态标量子类型,并且参数和结果类型是标量,则为语言定义的属性(函数)。
以来 Alloc 如上所述,正如RM 13.1所述,实现不需要在表示项中支持它。但是,实际的错误消息告诉我们 “Alloc”并不纯洁 ,所以GNAT告诉它如果支持这个 Alloc 很纯洁。
所以解决这个问题的一种方法就是制作 Alloc 纯,这意味着:添加 pragma Pure; 到包裹 St_Wa , 其中包含 Alloc 。这是否可行取决于包装,可能需要进行其他更改。
pragma Pure;
St_Wa
如果这不可行,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;