为什么 Ada 编译器会让范围违规通过?为什么我的类型声明是运行时实体? [英] Why does an Ada compiler let range violations pass? Why is my type declaration a runtime entity?

查看:33
本文介绍了为什么 Ada 编译器会让范围违规通过?为什么我的类型声明是运行时实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 Ada 编译器允许范围违规通过?它确实给出了警告,但是如果它在任何情况下都是错误的,为什么它让它通过呢?是否存在一种实用的行为?

Why does Ada compiler let range violations pass? It does give warning, but why does it let it pass if it is an error in any case? Is there a practical scenario in which this is a useful behaviour?

最重要的是:为什么类型声明是运行时实体?我的意思是代码示例的第 3 行是我希望提前评估的内容.我认为只有第 5 行会使它"成为可执行文件.为什么不?那东西有用吗?我是否在这里遗漏或误解了某些内容?

And most importantly: Why is type declaration a runtime entity? I mean the 3rd line of the code example is something I expect to be evaluated ahead of time. I thought that only the 5th line will "make it" into the executable. Why not? Is that something useful? Am I missing or misinterpreting something here?

with Ada.Text_IO;
procedure question is
    subtype Test is Natural range -1 .. 10;
begin
    Ada.Text_IO.Put_Line ("foobar");
end;

注意:结果与type Test is new Natural range -1..10;"相同

Note: Result is identical with "type Test is new Natural range -1..10;"

注意:GNAT 4.6

Note: GNAT 4.6

推荐答案

这条 comp.lang.ada 消息 建议您至少需要 -gnato -fstack-check 命令行选项才能使 Gnat 成为兼容的 Ada 编译器.

This comp.lang.ada message suggests that you need at least -gnato -fstack-check command line options for Gnat to be a compliant Ada compiler.

但这不是这里的问题:编译器确实会警告范围错误;用 Gnat 我得到:

However that's not the issue here : the compiler does warn about the range error; with Gnat I get:

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

以及运行时的明显错误.

and the obvious error at run time.

在这种情况下,因为范围是静态的,编译器可能会发现错误;但正如您所猜测的,一般情况下,直到运行时才能完全确定类型,如下例所示.

In this case because the range is static the compiler could have caught the error; but as you are guessing, in general the type cannot be fully determined until runtime, as in the following example.

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;

在您运行程序之前,这两个子类型都不知道.

Here neither subtype is known until you run the program.

declare 块显示了一个我觉得非常有用的相关模式,它不仅允许可变 [sub] 类型,而且在堆栈上分配可变大小的对象,以便在每次循环迭代时自动回收和重新调整大小.(您可以像在其他语言中一样使用new"进行分配,使用unchecked_deallocation"进行释放,但通常情况下,就像这里一样,根本不需要)

The declare block shows a related pattern I find very useful, that allows not just variable [sub]types, but allocates variable sized objects on the stack so that they are automatically reclaimed and re-sized on each loop iteration. (You could allocate with "new" and free with "unchecked_deallocation" as in other languages but very often, as here, there is simply no need)

这篇关于为什么 Ada 编译器会让范围违规通过?为什么我的类型声明是运行时实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆