为什么此Ada程序不引发约束错误?

时间:2018-08-02 01:36:54

标签: ada

我希望以下代码在编译时引发约束错误,但事实并非如此。它还不会在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;

1 个答案:

答案 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来覆盖它。

请注意,编译器仅向您发出警告。这是因为该程序是完全合法的,即使它将在运行时引发异常。 (无论使用rangeStatic_Predicate还是Dynamic_Predicate来指定子集,这都是相同的。)