为什么这个 Ada 程序没有抛出约束错误?
Why does this Ada program not throw a constraint error?
我预计以下代码会在编译时引发约束错误,但它没有。它也不会在 c2 赋值时抛出运行时错误。编辑:运行 带有-gnata 的编译器解决了编译警告问题,但没有解决缺少运行时错误问题。它是使用 GNAT FSF 编译的,没有优化,只是:gnatmake main 编辑:gnatmake -gnata main
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
subtype cat is Integer with Dynamic_Predicate => cat in 1 .. 9;
c1 : cat;
c2 : cat;
begin
c1 := 5;
c2 := 99;
end Main;
我认为 Dynamic_Predicate 行本质上等同于以下内容:
subtype cat is Integer range 1 .. 9;
当我构建您的示例时,我收到编译时警告和 运行 时错误:
$ gnatmake -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn -m -j0 main.adb
gcc-6 -c -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn main.adb
GNAT 6.3.0 20170516
Copyright 1992-2016, Free Software Foundation, Inc.
Compiling: main.adb
Source file time stamp: 2018-08-02 06:08:55
Compiled at: 2018-08-02 08:11:00
10. c2 := 99;
|
>>> warning: expression fails predicate check on "cat"
11 lines: No errors, 1 warning
gnatbind-6 -x main.ali
gnatlink-6 main.ali -fstack-check
$ ./main
raised SYSTEM.ASSERTIONS.ASSERT_FAILURE : Dynamic_Predicate failed at main.adb:10
$
我想问你的问题是 GCC/GNAT 中的默认断言策略是 Ignore
。我使用标志 -gnata
来覆盖它。
请注意,编译器只会给您一个警告。那是因为该程序是完全合法的,即使它会在 运行 时间引发异常。 (这个是一样的,不管你用range
、Static_Predicate
还是Dynamic_Predicate
来指定子集。)
我预计以下代码会在编译时引发约束错误,但它没有。它也不会在 c2 赋值时抛出运行时错误。编辑:运行 带有-gnata 的编译器解决了编译警告问题,但没有解决缺少运行时错误问题。它是使用 GNAT FSF 编译的,没有优化,只是:gnatmake main 编辑:gnatmake -gnata main
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
subtype cat is Integer with Dynamic_Predicate => cat in 1 .. 9;
c1 : cat;
c2 : cat;
begin
c1 := 5;
c2 := 99;
end Main;
我认为 Dynamic_Predicate 行本质上等同于以下内容:
subtype cat is Integer range 1 .. 9;
当我构建您的示例时,我收到编译时警告和 运行 时错误:
$ gnatmake -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn -m -j0 main.adb
gcc-6 -c -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn main.adb
GNAT 6.3.0 20170516
Copyright 1992-2016, Free Software Foundation, Inc.
Compiling: main.adb
Source file time stamp: 2018-08-02 06:08:55
Compiled at: 2018-08-02 08:11:00
10. c2 := 99;
|
>>> warning: expression fails predicate check on "cat"
11 lines: No errors, 1 warning
gnatbind-6 -x main.ali
gnatlink-6 main.ali -fstack-check
$ ./main
raised SYSTEM.ASSERTIONS.ASSERT_FAILURE : Dynamic_Predicate failed at main.adb:10
$
我想问你的问题是 GCC/GNAT 中的默认断言策略是 Ignore
。我使用标志 -gnata
来覆盖它。
请注意,编译器只会给您一个警告。那是因为该程序是完全合法的,即使它会在 运行 时间引发异常。 (这个是一样的,不管你用range
、Static_Predicate
还是Dynamic_Predicate
来指定子集。)