use*_*358 3 types runtime ada range compile-time
为什么Ada编译器会通过范围违规?它确实给出了警告,但是如果它在任何情况下都是错误的话,为什么它会通过呢?是否存在实际情况,这是一种有用的行为?
最重要的是:为什么类型声明是运行时实体?我的意思是代码示例的第3行是我希望提前评估的东西.我以为只有第5行才能"成为"可执行文件.为什么不?这有用吗?我在这里遗漏或误解了什么吗?
with Ada.Text_IO;
procedure question is
subtype Test is Natural range -1 .. 10;
begin
Ada.Text_IO.Put_Line ("foobar");
end;
Run Code Online (Sandbox Code Playgroud)
注意:结果与"类型测试是新的自然范围-1..10;"相同
注意:GNAT 4.6
这个comp.lang.ada消息表明,至少需要-gnato -fstack-checkGnat的命令行选项才能成为兼容的Ada编译器.
然而,这不是问题:编译器会警告范围错误; 和Gnat我得到:
gnatmake -gnato -fstack-check question
question.adb:3:35: warning: static value out of range of type "Standard.Natural"
question.adb:3:35: warning: "Constraint_Error" will be raised at run time
Run Code Online (Sandbox Code Playgroud)
和运行时的明显错误.
在这种情况下,因为范围是静态的,编译器可能已经捕获了错误; 但正如您猜测的那样,通常直到运行时才能完全确定类型,如下例所示.
with Ada.Text_IO;
with Ada.Command_Line;
procedure question is
subtype Arguments is Natural range 1 .. Ada.Command_Line.Argument_Count;
begin
for i in Arguments loop
Ada.Text_IO.Put_Line ("Argument " & integer'image(i) &
" is " & Ada.Command_Line.Argument(i));
declare
OneArg : constant String := Ada.Command_Line.Argument(i);
subtype Characters is Natural range OneArg'range;
begin
null; -- process the string here
end;
end loop;
end;
Run Code Online (Sandbox Code Playgroud)
在运行程序之前,这两个子类型都不知道.
声明块显示了一个我发现非常有用的相关模式,它不仅允许变量[sub]类型,而且在堆栈上分配可变大小的对象,以便在每次循环迭代时自动回收和重新调整它们.(您可以使用"new"分配,并使用"unchecked_deallocation"免费分配,就像在其他语言中一样,但很多时候,因为这里根本没有必要)