Valore non definito - Undefined value

Nell'informatica (in particolare, nella programmazione ), il valore indefinito è una condizione in cui un'espressione non ha un valore corretto , sebbene sia sintatticamente corretto. Un valore indefinito non deve essere confuso con una stringa vuota , un valore booleano "falso" o altri valori "vuoti" (ma definiti). A seconda delle circostanze, la valutazione su un valore indefinito può portare a un'eccezione oa un comportamento indefinito , ma in alcuni linguaggi di programmazione possono verificarsi valori indefiniti durante un corso normale e prevedibile dell'esecuzione del programma .

I linguaggi tipizzati dinamicamente di solito trattano i valori indefiniti in modo esplicito quando possibile. Ad esempio, Perl ha un undefoperatore che può "assegnare" tale valore a una variabile. In altri sistemi di tipo un valore indefinito può significare un valore sconosciuto, imprevedibile o semplicemente un errore del programma nel tentativo di valutarlo. I tipi nullable offrono un approccio intermedio; vedi sotto .

Manipolazione

Il valore di una funzione parziale non è definito quando il suo argomento è al di fuori del suo dominio di definizione . Ciò include numerosi casi aritmetici come la divisione per zero , la radice quadrata o il logaritmo di un numero negativo, ecc. Un altro esempio comune è l'accesso a un array con un indice fuori dai limiti, così come il valore in un array associativo per una chiave che non contiene. Esistono vari modi in cui queste situazioni vengono gestite nella pratica:

Valore riservato

Nelle applicazioni in cui i valori non definiti devono essere gestiti con garbo, è comune riservare uno speciale valore nullo distinguibile dai valori normali. Ciò risolve la difficoltà creando un valore definito per rappresentare il caso precedentemente non definito. Ci sono molti esempi di questo:

  • La libreria di I/O standard C riserva il valore speciale EOFper indicare che non è più disponibile l'input. La getchar()funzione restituisce il successivo carattere di input disponibile o EOFse non è più disponibile. (Il codice carattere ASCII definisce un carattere null per questo scopo, ma la libreria I/O stadard desidera essere in grado di inviare e ricevere caratteri null, quindi definisce un EOFvalore separato .)
  • Lo standard aritmetico a virgola mobile IEEE 754 definisce un valore speciale " non un numero " che viene restituito quando un'operazione aritmetica non ha un valore definito. Esempi sono la divisione per zero , o la radice quadrata o il logaritmo di un numero negativo .
  • Il linguaggio di query strutturato ha un NULLvalore speciale per indicare i dati mancanti.
  • Il linguaggio Perl consente di controllare la definizione di un'espressione tramite il defined()predicato.
  • Molti linguaggi di programmazione supportano il concetto di un puntatore nullo distinto da qualsiasi puntatore valido e spesso utilizzato come ritorno di errore.
  • Alcuni linguaggi consentono alla maggior parte dei tipi di essere annullabili, ad esempio C# .
  • La maggior parte delle chiamate di sistema Unix restituiscono il valore speciale −1 per indicare un errore.

Mentre i linguaggi tipizzati dinamicamente spesso assicurano che le variabili non inizializzate predefiniscano un valore null, i valori tipizzati staticamente spesso non lo fanno e distinguono i valori null (che sono ben definiti) dai valori non inizializzati (che non lo sono).

La gestione delle eccezioni

Alcuni linguaggi di programmazione hanno un concetto di gestione delle eccezioni per gestire la mancata restituzione di un valore. La funzione restituisce in un modo definito, ma non restituisce un valore, quindi non è necessario inventare un valore speciale da restituire.

Una variazione su questo è la gestione del segnale , che viene eseguita a livello di sistema operativo e non è integrata in un linguaggio di programmazione. I gestori di segnale possono tentare alcune forme di ripristino, come terminare parte di un calcolo, ma senza la stessa flessibilità della gestione delle eccezioni completamente integrata.

Funzioni di non ritorno

Una funzione che non restituisce mai ha un valore indefinito perché il valore non può mai essere osservato. A tali funzioni viene assegnato formalmente il tipo di fondo , che non ha valori. Gli esempi si dividono in due categorie:

Comportamento indefinito

Tutti i metodi precedenti di gestione dei valori indefiniti richiedono che l'indefinizione venga rilevata. Cioè, la funzione chiamata determina che non può restituire un risultato normale e intraprende un'azione per informare il chiamante. All'altra estremità dello spettro, il comportamento indefinito pone l'onere sul chiamante di evitare di chiamare una funzione con argomenti al di fuori del suo dominio. Non c'è limite a ciò che potrebbe accadere. Nella migliore delle ipotesi, un crash facilmente rilevabile ; nel peggiore dei casi, un errore sottile in un calcolo apparentemente non correlato.

(La definizione formale di "comportamento indefinito" include possibilità ancora più estreme, comprese cose come " fermati e prendi fuoco " e "fai volare i demoni dal tuo naso".)

L'esempio classico è un riferimento a un puntatore penzolante . È molto veloce dereferenziare un puntatore valido , ma può essere molto complesso determinare se un puntatore è valido. Pertanto, l'hardware del computer e i linguaggi di basso livello come il C non tentano di convalidare i puntatori prima di dereferenziarli, passando invece la responsabilità al programmatore. Ciò offre velocità a scapito della sicurezza.

Valore indefinito sensu stricto

La definizione rigorosa di un valore indefinito è un output superficialmente valido (non nullo) che è privo di significato ma non attiva un comportamento indefinito. Ad esempio, passare un numero negativo alla funzione radice quadrata inversa veloce produrrà un numero. Non è un numero molto utile, ma il calcolo verrà completato e restituirà qualcosa .

I valori indefiniti si verificano particolarmente spesso nell'hardware. Se un filo non trasporta informazioni utili, esiste ancora e ha un certo livello di tensione. La tensione non dovrebbe essere anormale (es. non una sovratensione dannosa ), ma il particolare livello logico non è importante.

La stessa situazione si verifica nel software quando viene fornito un buffer di dati ma non completamente riempito. Ad esempio, la strftimefunzione di libreria C converte un timestamp in un formato leggibile dall'uomo in un buffer di output fornito. Se il buffer di output non è abbastanza grande da contenere il risultato, viene restituito un errore e il contenuto del buffer non è definito.

Nell'altra direzione, la openchiamata di sistema in POSIX accetta tre argomenti: un nome file, alcuni flag e una modalità file. La modalità file viene utilizzata solo se i flag includono O_CREAT. è comune utilizzare una forma a due argomenti di open, che fornisce un valore indefinito per la modalità file, quando O_CREATviene omesso.

A volte è utile lavorare con valori così indefiniti in modo limitato. Il calcolo complessivo può ancora essere ben definito se il valore indefinito viene successivamente ignorato.

Ad esempio, il linguaggio C consente di convertire un puntatore in un numero intero, sebbene il valore numerico di tale numero intero non sia definito. Può essere ancora utile per il debug, per confrontare due puntatori per l'uguaglianza o per creare una lista collegata XOR .

La gestione sicura dei valori non definiti è importante nei sistemi di controllo della concorrenza ottimistici , che rilevano le race condition a posteriori. Ad esempio, la lettura di una variabile condivisa protetta da seqlock produrrà un valore indefinito prima di determinare che si è verificata una race condition. Quindi eliminerà i dati non definiti e ritenterà l'operazione. Questo produce un risultato definito fintanto che le operazioni eseguite sui valori non definiti non producono un comportamento indefinito a tutti gli effetti.

Altri esempi di valori indefiniti utili sono i generatori di numeri casuali e le funzioni hash . I valori specifici restituiti non sono definiti, ma hanno proprietà ben definite e possono essere utilizzati senza errori.

Notazione

Nella teoria della computabilità , l'indefinitezza di un'espressione è indicata come expr ↑ e la definizione come expr ↓.

Riferimenti

  1. ^ "indifferenza" . Documentazione Perl 5 . 2009-09-25 . Estratto il 26/03/2010 .
  2. ^ "definito" . Documentazione Perl 5 . 2009-09-25 . Estratto il 26/03/2010 .
  3. ^ a b Carr, Richard (1 ottobre 2006). "Tipi di dati numerici nullable C #" . Esercitazione sui fondamenti di C# . Estratto il 27/03/2010 .
  4. ^ "Demoni nasali" . File di gergo . Estratto il 12 giugno 2014 .

Guarda anche