1

I expected the following code to throw a constraint error on compilation, however it didn't. It also does not throw a runtime error on the c2 assignment. Edit: Running the compiler with -gnata solves the compilation warning issue, but does not solve the lack-of runtime error issue. It is compiled using GNAT FSF with no optimizations, just: gnatmake main Edit: 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;

I thought that the Dynamic_Predicate line would essentially be equivalent to the following :

subtype cat is Integer range 1 .. 9;
user3117351
  • 141
  • 1
  • 1
  • 9

1 Answers1

3

When I build your example, I get a compile-time warning, and a run-time error:

$ 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
$ 

I quess your problem is that the default assertion policy in GCC/GNAT is Ignore. I use the flag -gnata to override that.

Notice that the compiler only gives you a warning. That's because the program is completely legal, even if it will raise an exception at run-time. (This is the same, no matter if you use range, Static_Predicate or Dynamic_Predicate to specify the subset.)

Jacob Sparre Andersen
  • 6,733
  • 17
  • 22