Perché l'overflow è consentito silenziosamente in Ada?

5

Insuccesso silenzioso per un codice così banale. Come possono rivendicare un'elevata integrità?

with ada.text_io;
use  ada.text_io;
procedure overflow is
    procedure p (i: positive) is
        x: integer := integer'last;
    begin
        x := (x+i)/2;
        put_line (integer'image(x) & " should be positive");
    end;
begin
    p(10);
end;

Neanche un avvertimento del compilatore come "non può garantire la mancanza di overflow" o smth.

Questo sembra meno incline agli errori di alcune delle trappole del C ++ che i ragazzi di Ada amano sottolineare. Correggimi se sbaglio Mi piacerebbe avere un linguaggio migliore del C ++, ma continuo ad affrontare la complessità del linguaggio che dovrebbe proteggere da tutte le insidie e ancora.

    
posta cufizut 13.07.2016 - 20:54
fonte

2 risposte

7

Non tutti i compilatori Ada si comporteranno in questo modo. È necessario utilizzare una versione del compilatore GPL GNAT prima del 2015 o GCC di FSF precedente alla 5; a quel punto, GNAT non ha controllato l'overflow dei numeri interi per impostazione predefinita: dovevi compilare con -gnato .

Questo è stato indicato per perseguire l'efficienza, ma molti utenti hanno pensato che il guadagno di efficienza non valeva il costo di spiegare questo comportamento a nuovi utenti (e, a volte, non così nuovi). E, ovviamente, usare i tipi forniti dal compilatore come Integer non è la migliore pratica.

Al giorno d'oggi, il tuo programma viene compilato OK senza -gnato (ammesso senza avvisi, anche con -gnatwa ) ma viene eseguito con

$ ./overflow 

raised CONSTRAINT_ERROR : overflow.adb:7 overflow check failed

SPARK Ada rileva questo problema:

$ /opt/gnat-gpl-2016/bin/gnatprove -P overflow.gpr
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
overflow.adb:4:14: warning: subprogram "p" has no effect
overflow.adb:7:15: medium: overflow check might fail, in call inlined at overflow.adb:11 (e.g. when x = 2147483647)
overflow.adb:8:07: warning: no Global contract available for "Put_Line"
overflow.adb:8:07: warning: assuming "Put_Line" has no effect on global items
Summary logged in /Users/simon/tmp/so/gnatprove/gnatprove.out
    
risposta data 13.07.2016 - 22:06
fonte
3

Se un compilatore si comporta in questo modo, non è un compilatore Ada.

La mia ipotesi è che usi GCC (GNAT), che per qualche strana ragione richiede che tu passi una combinazione molto specifica di argomenti da linea di comando, per comportarti come un compilatore Ada:

  • -fstack-check - Stack overflow
  • -gnato - Overflow aritmetico
  • -gnat2012 - Utilizza Ada 2012 (anziché versioni precedenti della lingua)

E se vuoi che i contratti si comportino in modo ragionevole:

  • -gnata - Contratti e asserzioni
risposta data 14.07.2016 - 09:27
fonte

Leggi altre domande sui tag