异常没有被其名称捕获,但是在使用其他关键字时会被捕获?

时间:2015-01-02 20:35:41

标签: exception ada

异常没有被其名称捕获,但是在使用其他关键字时会被捕获?以下是我的代码

p.ads

 package p is 
  procedure proc ;
  end p;

p.adb

  package body p is
   my_exp:exception; -- user define exception
   procedure proc is
   begin
    raise my_exp; -- spreading exception
   end proc;
   end p;

p_main.adb

with p;
 with ada.text_io;
 use ada.text_io;
use p;
procedure p_main is
 begin
   proc;
  exception
when my_exp=>put(" my_exp");-- error but when others is used then.its good why?
  end p_main;

此处不显示广告网站my_exp的帐户my_exp,以及当使用其他关键字时它是如何显示的?

2 个答案:

答案 0 :(得分:3)

您的代码有很多语法错误。将完全代码复制并粘贴到问题中总是更好;您似乎重新输入了它,这使得很难区分原始代码中的拼写错误和实际错误。

忽略语法错误,这个:

exception
    when my_exp => put(" my_exp");

无法编译,因为名称my_exp不可见。 (如果你希望它可见,它应该在包规范中,但那不是你问的。)

如果您将when my_exp替换为when others,则可行;处理异常。这是因为when others子句处理引发的任何异常,无论其名称是否可见。

异常是程序运行时存在的条件。异常处理程序检测并处理该运行时实体。它不需要通过您用来定义它的任何标识符来引用它。

如果名称my_exp可见,则处理程序仍然(几乎可以肯定)不会使用该名称来识别异常。相反,编译器会创建一些运行时数据结构,允许通过引用特定内存地址来识别异常。确切的机制取决于编译器,除非您正在编写编译器,否则理解细节并不是非常重要。

已经引发异常的运行时检测以及异常,并不依赖于您在源代码中分配给异常的名称。

对名称my_exp的引用在编译时被拒绝 ,因为该名称在编译时不可见。

答案 1 :(得分:0)

首先要理解的是,如果您的软件包可以引发一个自定义异常而不是软件包规范所宣传的那样,那就是糟糕的设计,因为它会给软件包用户带来令人不快的意外。

所以正确的做法是在包中声明my_exp而不是将其隐藏在正文中。

package p is 
   my_exp:exception; -- user define exception

   procedure proc ;
end p;

然后修复所有其他琐碎的语法错误,并且您的程序按宣传的方式工作。

但即使你没有,并且“my_exp”在主程序中不可见,它的异常处理程序也可以正确识别它。

procedure p_main is
begin
   proc;
end p_main;

./ p_main
提出P.MY_EXP:p.adb:7

或者您可以自己操纵这些信息,以便更好地进行诊断或错误恢复

with Ada.Exceptions;  -- we need to process exception data

procedure p_main is
begin
   proc;
exception
   when  E : others => 
      put("something bad happened : " & Ada.Exceptions.Exception_Name(E));
end p_main;

./ p_main
发生了一件坏事:P.MY_EXP