确保在编译时覆盖异常
Ensure exception coverage at compile time
有没有办法让 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
pragma 来注释过程可以引发哪些异常,这是编译器强制执行的。该列表可以为空,即。 raises: []
,并且编译器将要求处理所有异常而不传播。 Ada 中是否有与此等效的内容?
如果你想处理所有可用的异常,你可以在exception
部分使用when others
。您的示例将如下所示:
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 能够做到这一点,因为 raises
pragma 是函数签名的一部分。因此,对于任何调用,可以静态知道可以引发哪些异常。在 Ada 中不是这样。
如果您认为编译器可以隐式地找出任何子例程可以引发哪些异常,那是对的,但不能解决问题,因为 Ada 允许分派调用和函数指针。对于这两个,您静态地不知道将被调用的函数(无论如何都没有指针分析,这超出了大多数编译器的范围),因此无法知道可能引发的异常(因为它们不是一部分签名)。
有没有办法让 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
pragma 来注释过程可以引发哪些异常,这是编译器强制执行的。该列表可以为空,即。 raises: []
,并且编译器将要求处理所有异常而不传播。 Ada 中是否有与此等效的内容?
如果你想处理所有可用的异常,你可以在exception
部分使用when others
。您的示例将如下所示:
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 能够做到这一点,因为 raises
pragma 是函数签名的一部分。因此,对于任何调用,可以静态知道可以引发哪些异常。在 Ada 中不是这样。
如果您认为编译器可以隐式地找出任何子例程可以引发哪些异常,那是对的,但不能解决问题,因为 Ada 允许分派调用和函数指针。对于这两个,您静态地不知道将被调用的函数(无论如何都没有指针分析,这超出了大多数编译器的范围),因此无法知道可能引发的异常(因为它们不是一部分签名)。