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

查看:99
本文介绍了为什么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?

最重要的是:为什么类型声明为什么是运行时实体?
我的意思是代码示例的第三行是我希望提前评估的内容。
我认为只有第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.

但是,这不是问题在这里:编译器会警告范围错误;与G我得到:

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

和运行时明显的错误。

在这种情况下,因为范围是静态的,编译器可能会发现错误;但正如您所猜测的那样,通常无法在运行时完全确定类型,如以下示例所示。

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.

声明块显示了一个我认为非常有用的相关模式,该模式不仅允许变量[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天全站免登陆