2014-12-03 37 views
1

我的代码如下。编译器不会让我使用判别式var来控制字符串name的大小。不能在记录中使用记录的判别式

procedure p is 

    type int is range 1 .. 10; 
    type my (var : int) is record 
     name : string (1 .. var); -- this var here is bad, why? 
    end record; 

    hh : my(6); 

begin 
    put (hh.name); 
end p; 

的错误消息是

p.adb:4:23: expected type "Standard.Integer" 
p.adb:4:23: found type "int" defined at line 2 
+0

为什么不使用'Ada.Strings.Bounded'? – trashgod 2014-12-03 12:40:14

+3

如果您使用的是Gnat,错误消息会告诉您到底发生了什么问题。如果你使'int'成为'Integer'的子类型而不是新类型,你可以发现其他错误。 – 2014-12-03 12:40:16

回答

3

这是由于Ada的强类型。 Ada允许你声明新的整数和浮点类型,它们彼此不兼容。最初的意图是防止意外地使用具有一种含义的值,就好像它们具有完全不相关的含义一样,例如,

type Length is digits 15; -- in meters 
type Mass is digits 15; -- in kilograms 
L : Length; 
M : Mass; 

M := L; -- error, caught at compile time 

由于“质量”变量不能保存长度,编译器会捕获这个没有任何意义的语句。如果一切都只是FloatLong_Float编译器将无法捕捉它。

你所做的是创建另一个整数类型,int。如上例所示,新类型的值不能自动转换为Integer,这是String索引的类型。 (String实际上定义为array (Positive range <>) of Character with Pack;,但Positive亚型Integer,和值可以PositiveInteger之间自动转换,因为它们实际上是一样的基类型的子类型。)

不幸的是,这是不允许:

type my(var : int) is record 
    name : string (1 .. Integer(var)); -- this var here is bad why? 
end record; 

由于Ada规则,判别式必须在此上下文中单独出现。所以你唯一的选择就是让int成为子类型:

subtype int is Integer range 0 .. 10; 
type my(var : int) is record 
    name : string (1 .. var); -- this var here is bad why? 
end record;