Assert.h: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica
Etichette: Inserimento tag INDEX o altre direttive Modifica da mobile Modifica da web per mobile
sistemo e semplifico
 
(2 versioni intermedie di 2 utenti non mostrate)
Riga 1:
{{Libreria_standard_C}}
{{LIBRERIA-STANDAR-C}}
{{TITOLOtitolo MINUSCOLOminuscolo}}
 
'''assert.h''' è il [[Direttiva di inclusione|file di intestazione]] della [[libreria standard del C]] che implementa il sistema di [[Asserzione (informatica)|asserzione]], definendo la macro <code>assert()</code>. Tale macro può essere utilizzata per verificare e controllare l'eventuale verificarsi di casi "impossibili" nel programma.
'''ASSET.H''' È L'[[HEADER FILE]] DELLA [[LIBRERIA STANDARD DEL C]] CHE DEFINISCE LA MACRO <CODE>ASSET()</CODE>. QUESTA MACRO IMPLEMENTA UN SISTEMA DI CONTROLLO DELLE [[ASSERZIONE LOGICA|ASSERZIONI]], CHE PUÒ ESSERE UTILIZZATO PER VERIFICARE E CONTROLLARE L'EVENTUALE VERIFICARSI DI CASI "IMPOSSIBILI" NEL PROGRAMMA.
 
== Descrizione ==
{| CLASSE="WIKITABLE"
{| class="wikitable"
|- BGCOLOR=#E9E9E9
|- bgcolor=#e9e9e9
! NOME || DESCRIZIONE
! Nome || Descrizione
|-
|<CODEcode>ASSETassert</CODEcode>|| QUANDOQuando QUESTAquesta MACROmacro VIENEviene ESEGUITAeseguita, ESSAessa COMPUTAcomputa ILil RISULTATOrisultato DELLdell'ESPRESSIONEespressione FRONTALEfornìtale: SEse ESSAessa RISULTArisulta ESSEREessere FALSAfalsa (INin ALTREaltre PAROLEparole, SEse ILil VALOREvalore FINALEfinale RISULTArisulta ESSEREessere 0), <CODEcode>ASSETassert</CODEcode> SCRIVEscrive ALCUNEalcune INFORMAZIONIinformazioni DIdi [[DEBUGdebug]] SUsu <CODEcode>STDERRstderr</CODEcode> Ee, SUCCESSIVAMENTEsuccessivamente, RICHIAMArichiama LAla FUNZIONEfunzione <CODEcode>ABORTabort()</CODEcode>. Le informazioni riportate LEsu INFORMAZIONIstderr RIPORTATE SU STDERR INCLUDONOincludono:
* ILil TESTOtesto DELLdell'ESPRESSIONEespressione CHEche HAha FORNITOfornito ILil RISULTATOrisultato 0
* ILil NOMEnome DELdel FILEfile SORGENTEsorgente (LAla MACROmacro PREDEFINITApredefinita FILE__FILE__)
* il numero della linea in cui si è fallita l'asserzione (la macro predefinita __LINE__)
* IL NUMERO DELLA LINEA IN CUI SI È FALLITA L'ASSERZIONE (LA MACRO PREDEFINITA LINEA
|}
L'utilità della macro <code>assert()</code> risiede nella semplicità con la quale si può verificare un'affermazione che si ritiene, in un dato contesto, banalmente ovvia: ad esempio, ricontrollare il valore di una variabile sulla quale si sono già effettuate delle verifiche. Nel codice che segue, la macro <code>assert()</code> viene utilizzata per controllare che il valore della variabile "scelta" sia effettivamente compreso nel range valido, nonostante l'uscita dal ciclo while implicitamente affermi la veridicità di questa condizione.
L'UTILITÀ DELLA MACRO <CODE>ASSERT()</CODE> RISIEDE NELLA SEMPLICITÀ CON LA QUALE SI PUÒ VERIFICARE UN'AFFERMAZIONE CHE SI RITIENE, IN UN DATO CONTESTO, BANALMENTE OVVIA: AD ESEMPIO, RICONTROLLARE IL VALORE DI UNA VARIABILE SULLA QUALE SI SONO GIÀ EFFETTUATE DELLE VERIFICHE. NEL CODICE CHE SEGUE, LA MACRO <CODE>ASSERT()</CODE> VIENE UTILIZZATA PER CONTROLLARE CHE IL IL VALORE DELLA VARIABILE "SCELTA" SIA EFFETTIVAMENTE COMPRESO NEL RANGER VALIDO, NONOSTANTE L'USCITA DAL CICLO WHILE IMPLICITAMENTE AFFERMI LA VERIDICITÀ DI QUESTA CONDIZIONE.
<syntaxhighlight lang="c" line="1">
 
INTint SCELTAscelta = 0;
do {
/* Visualizzo un menù con 4 scelte numerate da 1 a 4 */
scanf("%d", &scelta);
}
while (scelta<1 || scelta>4);
/* Primo blocco di operazioni eseguite in base al valore scelto */
/* VISUALIZZO UN MENU CON SCELTE NUMERATE da 1 a 4 */
SCANF("%d", &SCELTA);
ASSETassert(SCELTAscelta>=1 && SCELTAscelta <=4);
} WHILE (SCELTA<1 || SCELTA>4);
/* PRIMOSecondo BLOCCOblocco DIdi OPERAZIONIoperazioni ESEGUITEeseguite INin BASEbase ALal VALOREvalore SCELTOscelto */
</syntaxhighlight>
ASSET(SCELTA>=1 && SCELTA <=4);
/* SECONDO BLOCCO DI OPERAZIONI ESEGUITE IN in BASE AL VALORE SCELTO */
 
UTILIZZANDO <CODE>ASSERT()</CODE>, IL PROGRAMMATORE SI ACCERTA NUOVAMENTE CHE LA CONDIZIONE CHE AVEVA PROVOCATO L'USCITA DAL CICLO CICLO WHITE SIA ANCORA VERA: IN QUESTO CASO, AD ESEMPIO, VERIFICA DI NON AVER ACCIDENTALMENTE MODIFICATO IL VALORE DELLA VARIABILE <CODE>SCELTA</CODE> ALL'INTERNO DEL PRIMO BLOCCO DI OPERAZIONI.<BR />
L'UTILIZZO DI <CODE>ASSERT()</CODE> DOVREBBE ESSERE LIMITATO ALLA SOLA FASE DI SVILUPPO DI UN PROGRAMMA: PER LA BRUTALITÀ DEL METODO DI CHIUSURA DELL'ESEGUIBILE E PER LA SCARSEZZA DI INFORMAZIONI SULL'ERRORE FORNITE A VIDEO, RISULTEREBBE ABBASTANZA FRUSTRANTE PER L'UTENTE FINALE SE UTILIZZATO NELLA VERSIONE DEFINITIVA DI UN APPLICATIVO. BUONA PROGRAMMAZIONE VORREBBE, INFATTI, CHE VENGA SPIEGATO ALL'UTENTE QUALE CAUSA ABBIA SCATENATO IL PROBLEMA E, NEL CASO NON FOSSE POSSIBILE PROSEGUIRE L'ESECUZIONE, ALMENO PERMETTERE UN SALVATAGGIO PARZIALE DELLO STATO DEL PROGRAMMA. PER QUESTO, UN CODICE SIMILE A:
 
Utilizzando <code>assert()</code>, il programmatore si accerta nuovamente che la condizione che aveva provocato l'uscita dal ciclo while sia ancora vera: in questo caso, ad esempio, verifica di non aver accidentalmente modificato il valore della variabile <code>scelta</code> all'interno del primo blocco di operazioni.
INT *PTR = MALLOC(SIZEOF(INT) * 10);
ASSERT(PTR!= NULL);
/* UTILIZZO DI PTR */
 
L'utilizzo di <code>assert()</code> dovrebbe essere limitato alla sola fase di sviluppo di un programma. Infatti, la mancanza di verifica dell'asserzione provoca l'interruzione immediata dell'applicazione fornendo scarse informazioni in merito all'errore, anche se può essere usato l'[[operatore virgola]] per aggiungere informazioni all'espressione stampata, come in <code>assert(("2+2 fa 4", 2 + 2 == 5));</code>. Inoltre, la macro non dovrebbe essere adoperata in casi in cui ci sia una seppur piccola probabilità di fallimento, ad esempio in un'[[allocazione dinamica della memoria]]:<syntaxhighlight lang="c">
NON RAPPRESENTA UN USO OTTIMALE DI <CODE>ASSERT()</CODE>, PERCHÉ, ANCHE SE RARAMENTE, È POSSIBILE CHE UN[[ALLOCAZIONE DINAMICA DELLA MEMORIA|ALLOCAZIONE DINAMICA DI MEMORIA]] FALLISCA.
int *ptr = malloc(sizeof(int) * 10);
ASSERTassert(PTRptr != NULL);
</syntaxhighlight>
 
Quando il programmatore non ha più bisogno delle asserzioni, invece di eliminarle tutte manualmente può definire la costante <code>NDEBUG</code> prima di includere nel file sorgente l'header <code>assert.h</code>: in questo modo, la macro <code>assert()</code> viene espansa semplicemente in: <code>#define assert(ignore)((void) 0)</code>, eliminando quindi ogni possibile interazione con il programma. Dunque, in presenza di <code>NDEBUG</code> eventuali espressioni passate a <code>assert()</code> non verranno valutate.
QUANDO IL PROGRAMMATORE NON HA PIÙ BISOGNO DELLE ASSERZIONI, INVECE DI ELIMINARLE TUTTE MANUALMENTE PUÒ DEFINIRE LA COSTANTE <CODE>NDEBUG</CODE> PRIMA DI INCLUDERE NEL FILE SORGENTE L'HEADER <CODE>ASSERT.H</CODE>: IN QUESTO MODO, LA MACRO <CODE>ASSERT()</CODE> VIENE ESPANSA SEMPLICEMENTE in:
##DEFINE ASSERT(IGNORE)((VOID) 0)
ELIMINANDO QUINDI TUTTE LE POSSIBILI INTERAZIONI CON IL PROGRAMMA. BISOGNA QUINDI FAR NOTARE CHE, IN
QUESTO CASO, L'ESPRESSIONE PASSATA AD <CODE>ASSERT()</CODE> NON VIENE VALUTATA. COME ESPRESSIONI INSERITE ALL'INTERNO DI <CODE>ASSERT()</CODE> VANNO QUINDI ASSOLUTAMENTE EVITATE QUELLE CON EFFETTI COLLATERALI, COME AD ESEMPIO
ASSERT(*I++);
CHE FINIREBBERO PER MODIFICARE LA LOGICA DEL PROGRAMMA A SECONDA DELLA DEFINIZIONE O MENO DELLA COSTANTE <CODE>NDEBUG</CODE>. IN QUESTO ESEMPIO, INFATTI, AL TERMINE DELLA VERIFICA DELL'INSERZIONE, IL VALORE DEL PUNTATORE <CODE>i</CODE> RISULTEREBBE INCREMENTATO DI UNA UNITÀ NEL CASO <CODE>NDEBUG</CODE> NON SIA DEFINITO, MENTRE RESTEREBBE INALTERATO NEL CASO OPPOSTO.
 
== Voci correlate ==
Line 55 ⟶ 49:
* {{en}} [http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/assert.h.html assert.h] da The Open Group Base Specifications Issue 7
* {{cita web|https://www.gnu.org/software/libc/manual/html_node/Consistency-Checking.html|Consistency Checking - The GNU C Library|lingua=en}}
* {{cita web|1=http://www.cplusplus.com/reference/clibrary/cassert/|2=C Diagnostics Library|lingua=en|accesso=3 luglio 2012|dataarchivio=21 giugno 2012|urlarchivio=https://web.archive.org/web/20120621043500/http://www.cplusplus.com/reference/clibrary/cassert/|urlmorto=sì}}
* [https://web.archive.org/web/20101124224627/http://appuntilinux.mirror.garr.it/mirrors/appuntilinux/a2/a295.htm#almltitle4039 69.2 File «assert.h»] da [[Appunti di informatica libera]]