我希望以下代码在编译时引发约束错误,但事实并非如此。它还不会在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;
答案 0 :(得分:3)
构建示例时,会收到编译时警告和运行时错误:
$ 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
来指定子集,这都是相同的。)