遗留Ada代码在GNAT Studio编译报错及泛型实例化问题求助
问题分析与解决办法
一、初始代码的编译错误原因
type My_Test_Type is (<>);是Ada泛型形式参数的专用语法,用于声明未指定具体类型的离散类型(枚举或整数范围)。旧版PowerPC编译器可能支持非标准扩展,允许在普通代码中使用,但符合Ada标准的编译器(如GNAT 2021)会拒绝这种写法——普通类型声明必须明确完整的类型定义。
解决办法:
根据需求明确类型定义:
- 整数范围类型:
type My_Test_Type is range 1..10;(指定具体范围) - 枚举类型:
type My_Test_Type is (Val1, Val2, Val3);(指定枚举值)
二、泛型包与主程序的错误修正
1. 泛型包定义问题
原泛型包存在多处不符合Ada标准的问题:
- 泛型对象参数
My_Table : My_Table_Type;多余,且与过程参数重名,逻辑上也不合理(泛型应定义类型,而非具体对象) - 过程
InitMyTable的参数My_Table默认是in模式,无法修改数组元素,需改为in out模式 - 循环硬编码
1..1000,应使用泛型类型的固有范围My_Test_Type'Range
修正后的my_generic.ads:
package My_Generic is generic type My_Test_Type is (<>); -- 泛型离散类型参数 type My_Table_Type is array(My_Test_Type) of Integer; procedure InitMyTable(My_Table : in out My_Table_Type); end My_Generic;
修正后的my_generic.adb:
with GNAT.IO; use GNAT.IO; package body My_Generic is procedure InitMyTable (My_Table : in out My_Table_Type) is begin Put_Line("Entered InitMyTable"); -- 使用泛型类型的固有范围,替代硬编码值 for i in My_Test_Type'Range loop -- 将离散类型的i转换为Integer类型 My_Table(i) := Integer(i) + 1000; end loop; end InitMyTable; end My_Generic;
2. 主程序的实例化错误
原主程序的错误点:
- 声明变量时用
=而非Ada标准的:= - 错误使用
new实例化泛型过程(new用于动态分配对象,泛型过程实例化需用procedure ... is new ...语法) - 实例化时需明确或让编译器推导泛型参数
修正后的主程序代码:
with My_Generic; use My_Generic; with GNAT.IO; use GNAT.IO; procedure Main is -- 定义具体的离散类型 type My_Test_Type is range 1..10; -- 定义对应数组类型 type My_Table_Type is array(My_Test_Type) of Integer; -- 声明要初始化的数组对象 My_Table : My_Table_Type; -- 实例化泛型过程 procedure InitMyTable_i is new InitMyTable(My_Test_Type => My_Test_Type, My_Table_Type => My_Table_Type); begin Put_Line ("Initializing My table (<>)"); -- 调用实例化后的过程,传入数组对象 InitMyTable_i(My_Table); end Main;
也可以让编译器自动推导泛型参数,简化实例化语句:
procedure InitMyTable_i is new InitMyTable(My_Table_Type => My_Table_Type);
编译器会根据My_Table_Type的索引类型自动匹配My_Test_Type参数。
内容的提问来源于stack exchange,提问作者Neil Shore
相关产品推荐
相关产品推荐

