Come gestire la divisione per zero in una lingua che non supporta le eccezioni?


62

Sono nel mezzo dello sviluppo di un nuovo linguaggio di programmazione per risolvere alcuni requisiti aziendali e questo linguaggio è rivolto agli utenti meno esperti. Quindi non esiste supporto per la gestione delle eccezioni nella lingua e non mi aspetterei che la usino anche se l'ho aggiunta.

Ho raggiunto il punto in cui devo implementare l'operatore di divisione e mi chiedo come gestire al meglio una divisione per errore zero?

Mi sembra di avere solo tre possibili modi per gestire questo caso.

  1. Ignora l'errore e produce 0come risultato. Registrazione di un avviso, se possibile.
  2. Aggiungi NaNcome possibile valore per i numeri, ma ciò solleva domande su come gestire i NaNvalori in altre aree della lingua.
  3. Terminare l'esecuzione del programma e segnalare all'utente un grave errore.

L'opzione n. 1 sembra l'unica soluzione ragionevole. L'opzione n. 3 non è pratica in quanto questo linguaggio verrà utilizzato per eseguire la logica come cron notturno.

Quali sono le mie alternative alla gestione di una divisione per errore zero e quali sono i rischi associati all'opzione n. 1.


12
se hai aggiunto il supporto per le eccezioni e l'utente non l'ha rilevato, allora avresti l'opzione # 3
maniaco del cricchetto,

82
Sono curioso, che tipo di stupido requisito ti richiederebbe di creare un linguaggio di programmazione completamente nuovo? Nella mia esperienza, ogni linguaggio mai creato fa schifo (nel design o nell'esecuzione, spesso in entrambi) e ci è voluto uno sforzo irragionevolmente anche per ottenere così tanto. Ci sono alcune eccezioni alla prima, ma non alla seconda, e poiché sono facilmente <0,01% dei casi, probabilmente sono errori di misurazione ;-)

16
La maggior parte delle nuove lingue di @delnan sono state create per consentire alle regole aziendali di essere separate da come vengono implementate. L'utente non ha bisogno di sapere come è reject "Foo"stato implementato, ma semplicemente che rifiuta un documento se contiene la parola chiave Foo. Cerco di rendere la lingua più facile da leggere usando termini che l'utente ha familiarità. Dare a un utente il proprio linguaggio di programmazione consente loro di aggiungere regole di business senza dipendere dal personale tecnico.
Reactgular,

19
@Mathew Foscarini. Mai e poi mai, ignorare l'errore e restituire silenziosamente 0. Quando si fa una divisione, 0 può essere un valore perfettamente legale (per qualche motivo, c'è una cosa del genere in Power Basic, ed è davvero un dolore). Se divini numeri in virgola mobile, Nan o Inf sarebbero carini (dai un'occhiata a IEEE 754 per capire perché). Se dividi numeri interi, puoi interrompere il programma, dividere per 0 non dovrebbe mai essere consentito (beh, a meno che tu non voglia implementare un vero sistema di eccezioni).

16
Sono stato divertito e affascinato da un settore commerciale abbastanza complesso da giustificare un linguaggio di programmazione proprietario e completo di Turing, ma abbastanza lasco da tollerare risultati drasticamente inaccurati.
Mark E. Haase,

Risposte:


98

Sconsiglio vivamente il n. 1, perché ignorare gli errori è un pericoloso anti-schema. Può portare a bug difficili da analizzare. L'impostazione del risultato di una divisione da 0 a 0 non ha alcun senso, e continuare l'esecuzione del programma con un valore senza senso causerà problemi. Soprattutto quando il programma viene eseguito incustodito. Quando l'interprete del programma nota che c'è un errore nel programma (e una divisione per zero è quasi sempre un errore di progettazione), abortirlo e mantenere tutto così com'è di solito è preferito al riempimento del database con immondizia.

Inoltre, è improbabile che tu riesca a seguire attentamente questo schema. Prima o poi ti imbatterai in situazioni di errore che non possono essere ignorate (come l'esaurimento della memoria o un overflow dello stack) e dovrai comunque implementare un modo per terminare il programma.

L'opzione n. 2 (usando NaN) sarebbe un po 'di lavoro, ma non tanto quanto potresti pensare. Il modo in cui gestire NaN in diversi calcoli è ben documentato nello standard IEEE 754, quindi puoi probabilmente fare semplicemente la lingua in cui è scritto il tuo interprete.

A proposito: la creazione di un linguaggio di programmazione utilizzabile da non programmatori è qualcosa che stiamo cercando di fare dal 1964 (Dartmouth BASIC). Finora non abbiamo avuto successo. Ma buona fortuna comunque.


14
+1 grazie. Mi hai convinto a lanciare un errore e ora che ho letto la tua risposta non capisco perché stavo esitando. PHPha avuto una cattiva influenza su di me.
Reactgular,

24
Sì, l'ha fatto. Quando ho letto la tua domanda, ho immediatamente pensato che fosse una cosa molto simile a PHP produrre output errati e continuare a trasportare camion a fronte di errori. Ci sono buoni motivi per cui PHP è l'eccezione nel fare questo.
Gioele,

4
+1 per il commento BASIC. Non consiglio di usare NaNla lingua di un principiante, ma in generale un'ottima risposta.
Ross Patterson,

8
@Joel Se fosse vissuto abbastanza a lungo, Dijkstra avrebbe probabilmente detto "L'uso di [PHP] paralizza la mente; il suo insegnamento dovrebbe, quindi, essere considerato un reato".
Ross Patterson,

12
@Ross. "L'arroganza nell'informatica si misura nei nano-Dijkstras" - Alan Kay

33

1 - Ignora l'errore e produce 0come risultato. Registrazione di un avviso, se possibile.

Non è una buona idea. Affatto. Le persone inizieranno a dipendere da questo e se dovessi risolverlo, romperai molto codice.

2 - Aggiungi NaNcome possibile valore per i numeri, ma ciò solleva domande su come gestire i NaNvalori in altre aree della lingua.

Dovresti gestire NaN nel modo in cui lo fanno i runtime di altre lingue: ogni ulteriore calcolo produce anche NaN e ogni confronto (anche NaN == NaN) produce falso.

Penso che questo sia accettabile, ma non necessariamente nuovo arrivato amichevole.

3 - Terminare l'esecuzione del programma e segnalare all'utente un grave errore.

Questa è la migliore soluzione che penso. Con tali informazioni a disposizione, gli utenti dovrebbero essere in grado di gestire 0. È necessario fornire un ambiente di test, soprattutto se è previsto che venga eseguito una volta a notte.

C'è anche una quarta opzione. Trasforma la divisione in un'operazione ternaria. Ognuno di questi due funzionerà:

  • div (numeratore, denumeratore, alternative_result)
  • div (numeratore, denumeratore, alternativa_denumeratore)

Ma se fate NaN == NaNessere false, allora si dovrà aggiungere una isNaN()funzione di modo che gli utenti siano in grado di rilevare NaNs.
AJMansfield,

2
@AJMansfield: O che, o le persone attuano loro stessi: isNan(x) => x != x. Tuttavia, quando hai NaNtrovato il tuo codice di programmazione, non dovresti iniziare ad aggiungere isNaNcontrolli, ma piuttosto rintracciare la causa e fare i controlli necessari lì. Pertanto è importante NaNpropagarsi completamente.
back2dos,

5
NaNs sono principalmente contro-intuitivi. Nella lingua di un principiante, sono morti all'arrivo.
Ross Patterson,

2
@RossPatterson Ma un principiante può facilmente dire 1/0- devi farci qualcosa. Non esiste alcun risultato utile diverso da Info NaN- qualcosa che propagherà ulteriormente l'errore nel programma. Altrimenti l'unica soluzione è fermarsi con un errore a questo punto.
Mark Hurd,

1
L'opzione 4 potrebbe essere migliorata consentendo l'invocazione di una funzione, che a sua volta potrebbe eseguire qualsiasi azione necessaria per recuperare dall'inatteso 0 divisore.
CyberFonic,

21

Terminare l'applicazione in esecuzione con estremo pregiudizio. (Pur fornendo adeguate informazioni di debug)

Quindi istruisci i tuoi utenti a identificare e gestire le condizioni in cui il divisore potrebbe essere zero (valori immessi dall'utente, ecc.)


13

In Haskell (e simili in Scala), invece di buttare eccezioni (o di ritorno i riferimenti nulli) i tipi di wrapper Maybee Eitherpuò essere utilizzato. Con Maybel'utente ha la possibilità di verificare se il valore che ha ottenuto è "vuoto", oppure potrebbe fornire un valore predefinito quando "scartato". Eitherè simile, ma può essere utilizzato restituisce un oggetto (ad esempio una stringa di errore) che descrive il problema, se presente.


1
Vero, ma nota che Haskell non lo usa per divisione per zero. Invece, ogni tipo di Haskell ha implicitamente "bottom" come valore possibile. Questo non è come puntatori nulli nel senso che è il "valore" di un'espressione che non riesce a terminare. Ovviamente non è possibile verificare la nonterminazione come valore, ma nella semantica operativa i casi che non riescono a terminare fanno parte del significato di un'espressione. In Haskell, quel valore "bottom" gestisce anche ulteriori risultati di casi di errore come la error "some message"funzione in corso di valutazione.
Steve314,

Personalmente, se l'effetto dell'interruzione dell'intero programma è considerato valido, non so perché il codice puro non possa avere l'effetto di Haskellgenerare un'eccezione , ma sono solo io - non consente alle espressioni pure di generare eccezioni.
Steve314,

Penso che sia una buona idea perché oltre a lanciare un'eccezione, tutte le opzioni proposte non comunicano agli utenti che hanno commesso un errore. L'idea di base è che l'utente commette un errore con il valore che ha dato al programma, quindi il programma dovrebbe dire all'utente che ha dato un input errato (quindi l'utente può pensare a un modo per rimediare). Senza dire agli utenti il ​​loro errore, qualsiasi soluzione sembra così strana.
Informato il

Penso che questa sia la strada da percorrere ... Il linguaggio di programmazione Rust lo utilizza ampiamente nella sua libreria standard.
aochagavia,

12

Altre risposte hanno già considerato i meriti relativi delle tue idee. Ne propongo un altro: utilizzare l'analisi del flusso di base per determinare se una variabile può essere zero. Quindi puoi semplicemente impedire la divisione per variabili potenzialmente zero.

x = ...
y = ...

if y ≠ 0:
  return x / y    // In this block, y is known to be nonzero.
else:
  return x / y    // This, however, is a compile-time error.

In alternativa, avere una funzione di asserzione intelligente che stabilisce gli invarianti:

x = ...
require x ≠ 0, "Unexpected zero in calculation"
// For the remainder of this scope, x is known to be nonzero.

Ciò equivale a generare un errore di runtime (si evitano del tutto le operazioni non definite), ma presenta il vantaggio che non è nemmeno necessario colpire il percorso del codice per poter scoprire il potenziale errore. Può essere fatto in modo molto simile al normale controllo dei caratteri, valutando tutti i rami di un programma con ambienti di battitura nidificati per tracciare e verificare gli invarianti:

x = ...           // env1 = { x :: int }
y = ...           // env2 = env1 + { y :: int }
if y ≠ 0:         // env3 = env2 + { y ≠ 0 }
  return x / y    // (/) :: (int, int ≠ 0) → int
else:             // env4 = env2 + { y = 0 }
  ...
...               // env5 = env2

Inoltre, si estende naturalmente alla portata e al nullcontrollo, se la tua lingua ha tali caratteristiche.


4
Ottima idea, ma questo tipo di risoluzione dei vincoli è NP-completo. Immagina qualcosa di simile def foo(a,b): return a / ord(sha1(b)[0]). L'analizzatore statico non può invertire SHA-1. Clang ha questo tipo di analisi statica ed è ottimo per trovare bug superficiali ma ci sono molti casi che non è in grado di gestire.
Mark E. Haase,

9
questo non è NP-completo, questo è impossibile - dice fermare il lemma. Tuttavia, l'analizzatore statico non ha bisogno di risolverlo, può semplicemente fare una dichiarazione del genere e richiedere di aggiungere un'asserzione o una decorazione esplicite.
MK01,

1
@ MK01: In altre parole, l'analisi è "conservativa".
Jon Purdy,

11

Il numero 1 (inserire zero indicizzabile) è sempre errato. La scelta tra # 2 (propagare NaN) e # 3 (uccidere il processo) dipende dal contesto e idealmente dovrebbe essere un'impostazione globale, come in Numpy.

Se stai eseguendo un grande calcolo integrato, la propagazione di NaN è una cattiva idea perché alla fine si diffonderà e infetterà l'intero calcolo --- quando guardi i risultati al mattino e vedi che sono tutti NaN, tu ' dovrei buttare via i risultati e ricominciare comunque. Sarebbe stato meglio se il programma fosse terminato, hai ricevuto una chiamata nel cuore della notte e l'hai risolto --- almeno in termini di numero di ore sprecate.

Se stai facendo molti piccoli calcoli per lo più indipendenti (come calcoli di riduzione della mappa o in modo imbarazzantemente paralleli) e puoi tollerare che una percentuale di essi sia inutilizzabile a causa delle NaN, questa è probabilmente l'opzione migliore. Terminare il programma e non fare il 99% che sarebbe utile e utile a causa dell'1% malformato e diviso per zero potrebbe essere un errore.

Un'altra opzione, correlata ai NaN: la stessa specifica IEEE in virgola mobile definisce Inf e -Inf e questi vengono propagati in modo diverso rispetto a NaN. Ad esempio, sono abbastanza sicuro che Inf> qualsiasi numero e -Inf <qualsiasi numero, che sarebbe quello che volevi se la divisione per zero avvenisse perché lo zero doveva essere solo un piccolo numero. Se i tuoi input sono arrotondati e soffrono di errori di misura (come le misurazioni fisiche prese a mano), la differenza di due grandi quantità può portare a zero. Senza la divisione per zero, avresti ottenuto un numero elevato e forse non ti importa quanto sia grande. In tal caso, In e -Inf sono risultati perfettamente validi.

Può anche essere formalmente corretto --- basta dire che stai lavorando nei reali estesi.


Ma non possiamo dire se il denominatore fosse destinato a essere positivo o negativo, quindi la divisione potrebbe produrre + inf quando si desiderava -inf, o viceversa.
Daniel Lubarov,

È vero, l'errore di misurazione è troppo piccolo per distinguere tra + inf e -inf. Questo assomiglia più da vicino alla sfera di Riemann, in cui l'intero piano complesso è mappato su una palla con esattamente un punto infinito (il punto diametralmente opposto all'origine). Numeri positivi molto grandi, numeri negativi molto grandi e persino numeri immaginari e complessi molto grandi sono tutti vicini a quell'unico punto infinito. Con un piccolo errore di misurazione, non è possibile distinguerli.
Jim Pivarski,

Se stai lavorando in quel tipo di sistema, dovresti identificare + inf e -inf come equivalenti, così come devi identificare +0 e -0 come equivalenti, anche se hanno diverse rappresentazioni binarie.
Jim Pivarski,

8

3. Terminare l'esecuzione del programma e segnalare all'utente un grave errore.

[Questa opzione] non è pratica ...

Naturalmente è pratico: è responsabilità dei programmatori scrivere un programma che abbia effettivamente senso. La divisione per 0 non ha alcun senso. Pertanto, se il programmatore sta eseguendo una divisione, è anche sua responsabilità verificare in anticipo che il divisore non sia uguale a 0. Se il programmatore non riesce a eseguire quel controllo di validazione, allora dovrebbe rendersi conto di quell'errore non appena i risultati di calcolo possibili e denormalizzati (NaN) o errati (0) semplicemente non aiuteranno a tale riguardo.

L'opzione 3 sembra essere quella che ti avrei raccomandato, tra l'altro, di essere la più semplice, onesta e matematicamente corretta.


4

Mi sembra una cattiva idea eseguire compiti importanti (ad es. "Cronologia notturna") in un ambiente in cui gli errori vengono ignorati. È una terribile idea renderla una caratteristica. Questo esclude le opzioni 1 e 2.

L'opzione 3 è l'unica soluzione accettabile. Le eccezioni non devono far parte del linguaggio, ma fanno parte della realtà. Il tuo messaggio di risoluzione deve essere il più specifico e informativo possibile sull'errore.


3

IEEE 754 in realtà ha una soluzione ben definita per il tuo problema. Gestione delle eccezioni senza l'utilizzo di exceptions http://en.wikipedia.org/wiki/IEEE_floating_point#Exception_handling

1/0  = Inf
-1/0 = -Inf
0/0  = NaN

in questo modo tutte le tue operazioni hanno matematicamente un senso.

\ lim_ {x \ to 0} 1 / x = Inf

A mio avviso, seguire IEEE 754 ha più senso poiché garantisce che i tuoi calcoli siano corretti come su un computer e che tu sia anche coerente con il comportamento di altri linguaggi di programmazione.

L'unico problema che si presenta è che Inf e NaN contamineranno i tuoi risultati e i tuoi utenti non sapranno esattamente da dove provenga il problema. Dai un'occhiata a una lingua come Julia che lo fa abbastanza bene.

julia> 1/0
Inf

julia> -1/0
-Inf

julia> 0/0
NaN

julia> a = [1,1,1] ./ [2,1,0]
3-element Array{Float64,1}:
   0.5
   1.0
 Inf

julia> sum(a)
Inf

julia> a = [1,1,0] ./ [2,1,0]
3-element Array{Float64,1}:
   0.5
   1.0
 NaN

julia> sum(a)
NaN

L'errore di divisione viene propagato correttamente attraverso le operazioni matematiche ma alla fine l'utente non sa necessariamente da quale operazione deriva l'errore.

edit:Non ho visto la seconda parte della risposta di Jim Pivarski che è sostanzialmente ciò che sto dicendo sopra. Colpa mia.


2

SQL, facilmente il linguaggio più utilizzato dai non programmatori, fa il n. 3, per tutto ciò che vale. Nella mia esperienza osservando e aiutando i non programmatori a scrivere SQL, questo comportamento è generalmente ben compreso e facilmente compensato (con un'istruzione case o simili). Aiuta il messaggio di errore che tende ad essere abbastanza diretto, ad esempio in Postgres 9 ottieni "ERRORE: divisione per zero".


2

Penso che il problema sia "rivolto agli utenti inesperti. -> Quindi non c'è supporto per ..."

Perché pensi che la gestione delle eccezioni sia problematica per gli utenti alle prime armi?

Cosa è peggio? Hai una funzione "difficile" o non hai idea del perché sia ​​successo qualcosa? Cosa potrebbe confondere di più? Un arresto anomalo con un dump principale o "Errore irreversibile: Divide by Zero"?

Invece, penso che sia MOLTO meglio puntare a GRANDI errori di messaggio. Quindi invece: "Calcolo errato, dividi 0/0" (es .: mostra sempre i DATI che causano il problema, non solo il tipo di problema). Guarda come PostgreSql fa gli errori del messaggio, che sono grandi IMHO.

Tuttavia, puoi esaminare altri modi per lavorare con eccezioni come:

http://dlang.org/exception-safe.html

Ho anche sognato di costruire un linguaggio, e in questo caso penso che mescolare un Forse / Opzionale con normali eccezioni potrebbe essere il migliore:

def openFile(fileName): File | Exception
    if not(File.Exist(fileName)):
        raise FileNotExist(fileName)
    else:
        return File.Open()

#This cause a exception:

theFile = openFile('not exist')

# But this, not:

theFile | err = openFile('not exist')

1

A mio avviso la tua lingua dovrebbe fornire un meccanismo generico per rilevare e gestire gli errori. Gli errori di programmazione dovrebbero essere rilevati al momento della compilazione (o il più presto possibile) e dovrebbero normalmente portare alla conclusione del programma. Gli errori derivanti da dati imprevisti o errati o da condizioni esterne impreviste devono essere rilevati e resi disponibili per le azioni appropriate, ma consentire al programma di continuare ogni volta che è possibile.

Le azioni plausibili includono (a) terminare (b) richiedere all'utente un'azione (c) registrare l'errore (d) sostituire un valore corretto (e) impostare un indicatore da testare nel codice (f) invocare una routine di gestione degli errori. Quali di questi rendi disponibili e con quali mezzi sono le scelte che devi fare.

In base alla mia esperienza, errori di dati comuni come conversioni errate, divisione per zero, overflow e valore fuori intervallo sono favorevoli e dovrebbero essere gestiti per impostazione predefinita sostituendo un valore diverso e impostando un flag di errore. Il (non programmatore) che utilizza questa lingua vedrà i dati difettosi e comprenderà rapidamente la necessità di controllare gli errori e gestirli.

[Per un esempio, considera un foglio di calcolo Excel. Excel non termina il foglio di calcolo perché un numero è traboccato o altro. La cella ottiene uno strano valore e vai a scoprire perché e risolverlo.]

Quindi, per rispondere alla tua domanda: non dovresti certo terminare. Potresti sostituire NaN ma non dovresti renderlo visibile, assicurati solo che il calcolo sia completato e generi uno strano valore elevato. E imposta un flag di errore in modo che gli utenti che ne hanno bisogno possano determinare che si è verificato un errore.

Divulgazione: ho creato proprio una tale implementazione del linguaggio (Powerflex) e ho affrontato esattamente questo problema (e molti altri) negli anni '80. Negli ultimi 20 anni ci sono stati progressi scarsi o nulli nelle lingue per i non programmatori e attirerai un sacco di critiche per averci provato, ma spero davvero che tu abbia successo.


1

Mi è piaciuto l'operatore ternario in cui si fornisce un valore alternativo nel caso in cui il denumeratore sia 0.

Un'altra idea che non ho visto è quella di produrre un valore "non valido" generale. Un generale "questa variabile non ha un valore perché il programma ha fatto qualcosa di male", che porta con sé una traccia dello stack completo. Quindi, se si utilizza mai quel valore ovunque, il risultato è di nuovo non valido, con la nuova operazione tentata in cima (ovvero se il valore non valido viene mai visualizzato in un'espressione, l'intera espressione restituisce non valida e non viene tentata alcuna chiamata di funzione; un'eccezione sarebbe essere operatori booleani - vero o non valido è vero e falso e non valido è falso - potrebbero esserci anche altre eccezioni). Una volta che quel valore non viene più indicato da nessuna parte, si registra una bella descrizione lunga dell'intera catena in cui le cose erano sbagliate e si continua a fare affari come al solito. Forse e-mail la traccia al lead del progetto o qualcosa del genere.

Qualcosa come la monade Maybe, in pratica. Funzionerà con qualsiasi altra cosa che può fallire, e puoi permettere alle persone di costruire i propri invalidi. E il programma continuerà a funzionare fino a quando l'errore non è troppo profondo, il che è ciò che è veramente desiderato qui, credo.


1

Ci sono due ragioni fondamentali per una divisione per zero.

  1. In un modello preciso (come numeri interi), si ottiene una divisione per zero DBZ perché l'input è errato. Questo è il tipo di DBZ che molti di noi pensano.
  2. Nel modello non preciso (come il pt mobile), potresti ottenere un DBZ a causa dell'errore di arrotondamento anche se l'input è valido. Questo è ciò a cui normalmente non pensiamo.

Per 1. devi comunicare agli utenti che hanno commesso un errore perché sono i responsabili e sono quelli che sanno meglio come porre rimedio alla situazione.

Per 2. Questo non è un errore dell'utente, puoi indicare l'algoritmo, l'implementazione dell'hardware, ecc. Ma questo non è un errore dell'utente, quindi non dovresti terminare il programma o persino lanciare un'eccezione (se consentito che non è in questo caso). Quindi una soluzione ragionevole è quella di continuare le operazioni in modo ragionevole.

Vedo che la persona che ha posto questa domanda ha chiesto il caso 1. Quindi è necessario comunicare di nuovo all'utente. Utilizzando qualunque standard a virgola mobile, Inf, -Inf, Nan, IEEE non si adatta a questa situazione. Strategia fondamentalmente sbagliata.


0

Non consentire nella lingua. Vale a dire, non consentire la divisione per un numero fino a quando non è evidentemente zero, di solito testandolo prima. Vale a dire.

int div = random(0,100);
int b = 10000 / div; // Error E0000: div might be zero

Per fare ciò è necessario un nuovo tipo numerico, un numero naturale, anziché un numero intero. Potrebbe essere ... difficile ... da affrontare.
Servito il

@Servy: No, non lo faresti. Perchè vorresti? Hai bisogno di logica nel compilatore per determinare possibili valori, ma lo vuoi comunque (per motivi di ottimizzazione).
Salterio

Se non si dispone di un tipo diverso, uno per zero e uno per valori diversi da zero, non si sarebbe in grado di risolvere il problema nel caso generale. O avresti falsi positivi e costringi l'utente a controllare lo zero molto più spesso di quanto dovrebbero effettivamente, oppure creerai situazioni in cui possono ancora dividere per zero.
Servito il

@Servy: ti sbagli: un compilatore può tracciare quello stato senza bisogno di un tale tipo, e per esempio GCC lo fa già. Ad esempio, il tipo C intconsente valori zero, ma GCC può ancora determinare dove nel codice specifici non possono essere zero.
MSalters,

2
Ma solo in alcuni casi; non può farlo, con una precisione del 100%, in tutti i casi. Avrai falsi positivi o falsi negativi. Questo è dimostrabilmente vero. Ad esempio, potrei creare uno snippet di codice che potrebbe anche non essere completo . Se il compilatore non può nemmeno sapere se è finito, come può sapere se l'int risultante è diverso da zero? Può catturare semplici casi ovvi, ma non tutti i casi.
Servito il

0

Mentre scrivi un linguaggio di programmazione, dovresti trarre vantaggio dal fatto e rendere obbligatorio includere un'azione per escogitare secondo lo stato zero. a <= n / c: 0 div-by-zero-action

So che ciò che ho appena suggerito è essenzialmente l'aggiunta di un "goto" al tuo PL.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.