ada - Preconditions don't work with GNAT? -
i'm still kind of new ada , think i'm misunderstanding use of preconditions, because looking through gnat rm seems checks aren't performed @ runtime. also, gnat rm precondition here doesn't specifiy exception thrown if precondition not met.
here code i'm trying:
procedure test begin generic type element_type private; use system.storage_elements; procedure byte_copy (destination : out element_type; source : in element_type; size : in storage_count := element_type'size) pre => size <= destination'size , size <= source'size; procedure byte_copy (destination : out element_type; source : in element_type; size : in storage_count := element_type'size) subtype byte_array storage_array (1 .. size / system.storage_unit); write, read : byte_array; write'address use destination'address; read'address use source'address; begin ada.text_io.put_line("size copy =" & size'img & " , source'size =" & source'size'img); if size > destination'size or else size > source'size raise constraint_error "source'size < size or else > destination'size"; end if; n in byte_array'range loop write (n) := read (n); end loop; end byte_copy; procedure integer_copy new byte_copy(integer); use type system.storage_elements.storage_count; a, b : integer; begin := 5; b := 987; ada.text_io.put_line ("a =" & a'img); ada.text_io.put_line ("b =" & b'img); integer_copy (a, b, integer'size / 2); ada.text_io.put_line ("a = " & a'img); ada.text_io.put_line ("b = " & b'img); integer_copy (a, b, integer'size * 2); ada.text_io.put_line ("a =" & a'img); ada.text_io.put_line ("b =" & b'img); end test;
if understand things correctly, programme should raise unspecified exception before calling put_line procedure. can see when run programme, procedure called invalid size argument violates precondition destination'size ≥ size ≤ source'size
. instead, have place if
statement catch error , raise exception constraint_error keep things sane.
$ ./test = 5 b = 987 size copy = 16 , source'size = 32 = 987 b = 987 size copy = 64 , source'size = 32 raised constraint_error : source'size < size or else > destination'size
i have tried variations adding pragma precondition ( ... )
doesn't work either.
one weird thing programme compiles if repeat with pre =>
clause in generic procedure body/definition. doesn't allow procedures , raises error (i.e., preconditions should in formal declarations, not in definition). generic procedures exception in case?
i'm surprised use clause can added in generic procedure declarations. makes defining formal parameter names easier (ones obscenely long) looks more bug because cannot done normal/regular procedure declarations.
p.s. wanted implement closest possible imitation of memcpy() c, in ada language learning purposes.
you need enable assertions compiling -gnata
:
$ gnatmake -gnat12 -gnata test.adb gcc -c -gnat12 -gnata test.adb gnatbind -x test.ali gnatlink test.ali gnatlink: warning: executable name "test" may conflict shell command $ ./test = 5 b = 987 size copy = 16 , source'size = 32 = 987 b = 987 raised system.assertions.assert_failure : failed precondition test.adb:13 instantiated @ test.adb:39
pragma assertion_policy isn't implemented in fsf gnat <= 4.8 (well, can't use turn checks on or off). however, is implemented in gnat gpl 2013; if you're not using gnat project files, mean creating file gnat.adc
containing
pragma assertion_policy (check);
minor point: 'size
in bits, not bytes, storage_count
isn't right type it!
Comments
Post a Comment