异常不是用它的名字捕获的,而是在使用其他关键字时捕获的?

Exception is not being caught with its name but it is caught when others keyword is used?

异常没有被它的名字捕获,但是当使用 others 关键字时它被捕获?下面是我的代码

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;

A/c 到 adacore 站点 my_exp 在此处不可见,那么当使用其他关键字时如何显示?

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

忽略语法错误,这个:

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

编译失败,因为名称 my_exp 不可见。 (如果你想让它可见,它应该在包规范中,但这不是你要求的。)

如果将 when my_exp 替换为 when others,它会起作用;处理异常。这是因为 when others 子句处理 任何已引发的 异常,无论其名称是否可见。

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

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

运行-time 检测异常已被引发,以及它是哪个异常,不取决于您在源代码中分配给异常的名称。

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

首先要了解的是,如果您的包可以引发包规范未公布的自定义异常,那么这就是糟糕的设计,因为它会给包用户带来不愉快的意外。

所以正确的做法是在包中声明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