确保在编译时覆盖异常

问题描述

是否可以通过GNAT来确保所有异常情况都得到处理?

举个例子:

   package IO renames Ada.Text_IO;
   package EIO renames Ada.IO_Exceptions;

   procedure Open_File (File : in out IO.File_Type) is
   begin
      IO.Open (File,IO.In_File,"example.txt");
   exception
      when EIO.Use_Error =>
         IO.Put_Line ("Use!");
      when EIO.Device_Error =>
         IO.Put_Line ("Device!");
   end Open_File;

Open也可以提出Name_Error,因此我希望GNAT警告该案件尚未得到处理。

我发现了pragma Restrictions (No_Exception_Propagation),但这似乎也将检查应用于标准库调用,因此Open变得不可用,因为它本身会传播异常。如果将其应用于示例,则会得到:

14:07: warning: pragma Restrictions (No_Exception_Propagation) in effect
14:07: warning: this handler can never be entered,and has been removed
16:07: warning: pragma Restrictions (No_Exception_Propagation) in effect
16:07: warning: this handler can never be entered,and has been removed

例如,我想从另一种语言获得的内容; Nim具有raises杂注以注释过程可引发的异常,编译器将其强制执行。该列表可以为空,即。 raises: [],并且编译器将要求所有异常都将被处理且不会传播。在Ada中有与此等效的东西吗?

解决方法

如果要处理所有可用的异常,可以在when others部分中使用exception。您的示例将如下所示:

package IO renames Ada.Text_IO;
package EIO renames Ada.IO_Exceptions;

procedure Open_File (File : in out IO.File_Type) is
begin
   IO.Open (File,IO.In_File,"example.txt");
exception
   when An_Exception : others =>
      IO.Put_Line (EIO.Exception_Message(An_Exception));
end Open_File;

如果要以单独的方式处理每个异常,则必须分别列出每个异常(如您的示例所示)。但是编译器不会警告您有关缺少异常处理程序的信息。

,

在Ada中是不可能的。

Nim之所以能够做到这一点,是因为class TicketComment < ApplicationRecord after_save :extract_mentions after_commit :notify def extract_mentions current_mentions = mentions.map(&:user).map(&:username) new_mentions = description.scan(/(?<=^|(?<=[^a-zA-ZÀ-ž0-9_-]))@([a-zA-ZÀ-ž]+[a-zA-ZÀ-ž0-9_]+)/).flatten mentions_to_add = new_mentions - current_mentions mentions_to_remove = current_mentions - new_mentions users_to_add = User.select(:id).where("username IN (?)",mentions_to_add.flatten).map(&:id) users_to_remove = User.select(:id).where("username IN (?)",mentions_to_remove.flatten).map(&:id) users_to_add&.each do |id_to_add| mentions.create(user_id: id_to_add) end mentions.where(user_id: users_to_remove).destroy_all end def notify user_ids = ticket.participants.pluck(:id) - [Current.user.id] TicketCommentMailer.comment_added(id,user_ids).deliver_later end end 编译指示是函数签名的一部分。因此,对于任何调用,静态地知道可以引发哪些异常。在Ada中不是这种情况。

如果您认为编译器可以隐式找出任何子例程可以引发哪些异常,那是对的,但不能解决问题,因为Ada允许分派调用和函数指针。对于这两种方法,您都不知道将被静态调用的函数(无论如何都没有指针分析,对于大多数编译器而言,这是超出范围的),因此无法知道可能引发的异常(因为它们不是一部分)签名。)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...