Ho studiato tutorial di OpenCV e mi sono imbattuto nella assert
funzione; Che cosa fa?
Ho studiato tutorial di OpenCV e mi sono imbattuto nella assert
funzione; Che cosa fa?
Risposte:
assert
termina il programma (di solito con un messaggio che cita la dichiarazione di asserzione) se il suo argomento risulta falso. È comunemente usato durante il debug per rendere più evidente il fallimento del programma se si verifica una condizione imprevista.
Per esempio:
assert(length >= 0); // die if length is negative.
Puoi anche aggiungere un messaggio più informativo da visualizzare in caso di errore:
assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");
Oppure così:
assert(("Length can't possibly be negative! Tell jsmith", length >= 0));
Quando si esegue una build di rilascio (non di debug), è anche possibile rimuovere l'overhead delle assert
istruzioni di valutazione definendo la NDEBUG
macro, in genere con uno switch del compilatore. Il corollario di questo è che il tuo programma non dovrebbe mai fare affidamento sulla macro assert in esecuzione.
// BAD
assert(x++);
// GOOD
assert(x);
x++;
// Watch out! Depends on the function:
assert(foo());
// Here's a safer way:
int ret = foo();
assert(ret);
Dalla combinazione del programma che chiama abort () e che non si garantisce che faccia nulla, le asserzioni dovrebbero essere usate solo per testare cose che lo sviluppatore ha assunto piuttosto che, ad esempio, l'utente inserendo un numero anziché una lettera (che dovrebbe essere gestito con altri mezzi).
assert
Solitamente solleva un'eccezione" - in C ++ non genera "eccezione", chiama abort ... è un po 'diverso.
#
personaggio non introduce un commento.
assert("error message", expression)
L' affermazione del computer assert è analoga all'affermazione assicurarsi in inglese.
Date un'occhiata al
programma di esempio assert () in C ++
Molti compilatori offrono una macro assert (). La macro assert () restituisce VERO se il suo parametro valuta VERO e intraprende un qualche tipo di azione se valuta FALSO. Molti compilatori interromperanno il programma su un assert () che fallisce; altri genereranno un'eccezione
Una potente funzionalità della macro assert () è che il preprocessore non lo comprime in alcun codice se DEBUG non è definito. È di grande aiuto durante lo sviluppo e quando il prodotto finale viene spedito non ci sono penalità di prestazione né aumento delle dimensioni della versione eseguibile del programma.
Per esempio
#include <stdio.h>
#include <assert.h>
void analyze (char *, int);
int main(void)
{
char *string = "ABC";
int length = 3;
analyze(string, length);
printf("The string %s is not null or empty, "
"and has length %d \n", string, length);
}
void analyze(char *string, int length)
{
assert(string != NULL); /* cannot be NULL */
assert(*string != '\0'); /* cannot be empty */
assert(length > 0); /* must be positive */
}
/**************** Output should be similar to ******************
The string ABC is not null or empty, and has length 3
La funzione assert () può diagnosticare i bug del programma. In C, è definito in <assert.h>
, e in C ++ è definito in <cassert>
. Il suo prototipo è
void assert(int expression);
L'espressione argomento può essere qualsiasi cosa tu voglia testare - una variabile o qualsiasi espressione C. Se l'espressione restituisce VERO, assert () non fa nulla. Se expression restituisce FALSE, assert () visualizza un messaggio di errore su stderr e interrompe l'esecuzione del programma.
Come usi assert ()? Viene utilizzato più frequentemente per rintracciare i bug del programma (che sono distinti dagli errori di compilazione). Un bug non impedisce la compilazione di un programma, ma provoca risultati errati o l'esecuzione non corretta (blocco, ad esempio). Ad esempio, un programma di analisi finanziaria che stai scrivendo potrebbe occasionalmente dare risposte errate. Sospetti che il problema sia causato dalla variabile interest_rate che assume un valore negativo, cosa che non dovrebbe mai accadere. Per verificare ciò, inserire la dichiarazione
assert (tasso_interesse> = 0); nelle posizioni del programma in cui viene utilizzato interest_rate. Se la variabile diventa negativa, la macro assert () ti avvisa. È quindi possibile esaminare il codice pertinente per individuare la causa del problema.
Per vedere come funziona assert (), esegui il seguente programma di esempio . Se si immette un valore diverso da zero, il programma visualizza il valore e termina normalmente. Se si inserisce zero, la macro assert () forza la chiusura anomala del programma. Il messaggio di errore esatto che vedi dipenderà dal tuo compilatore, ma ecco un esempio tipico:
Asserzione non riuscita: x, elenco file19_3.c, riga 13 Si noti che, affinché assert () funzioni, il programma deve essere compilato in modalità debug. Fare riferimento alla documentazione del compilatore per informazioni sull'abilitazione della modalità debug (come spiegato in un momento). Quando successivamente compilerai la versione finale in modalità di rilascio, le macro assert () sono disabilitate.
int x;
printf("\nEnter an integer value: ");
scanf("%d", &x);
assert(x >= 0);
printf("You entered %d.\n", x);
return(0);
Immettere un valore intero: 10
Hai inserito 10.
Immettere un valore intero: -1
Messaggio di errore: chiusura anomala del programma
Il messaggio di errore potrebbe essere diverso, a seconda del sistema e del compilatore, ma l'idea generale è la stessa.
Cose come 'solleva eccezioni' e 'interrompe l'esecuzione' potrebbero essere vere per la maggior parte dei compilatori, ma non per tutti. (A proposito, ci sono affermazioni che fanno davvero eccezione?)
Ecco un significato interessante, leggermente diverso, di assert usato da c6x e altri compilatori TI: dopo aver visto certe affermazioni assert, questi compilatori usano le informazioni in quella affermazione per eseguire alcune ottimizzazioni. Wicked.
Esempio in C:
int dot_product(short *x, short *y, short z)
{
int sum = 0
int i;
assert( ( (int)(x) & 0x3 ) == 0 );
assert( ( (int)(y) & 0x3 ) == 0 );
for( i = 0 ; i < z ; ++i )
sum += x[ i ] * y[ i ];
return sum;
}
Questo dice al compilatore che le matrici sono allineate su limiti a 32 bit, quindi il compilatore può generare istruzioni specifiche fatte per quel tipo di allineamento.
Bozza standard C ++ 11 N3337
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
19.3 Asserzioni
1 L'intestazione <cassert>, descritta nella (Tabella 42), fornisce una macro per documentare le asserzioni del programma C ++ e un meccanismo per disabilitare i controlli delle asserzioni.
2 I contenuti sono gli stessi dell'intestazione della libreria C standard <assert.h>.
Tiraggio standard C99 N1256
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
7.2 Diagnostica <assert.h>
1 L'intestazione
<assert.h>
definisce la macro di asserzione e fa riferimento a un'altra macro,NDEBUG
che non è definita da<assert.h>
. SeNDEBUG
è definito come un nome macro nel punto nel file di origine in cui è incluso <assert.h>, la macro assert è definita semplicemente come#define assert(ignore) ((void)0)
La macro assert viene ridefinita in base allo stato corrente di NDEBUG ogni volta che
<assert.h>
viene inclusa.2. La macro di asserzione deve essere implementata come una macro, non come una funzione effettiva. Se la definizione di macro viene soppressa per accedere a una funzione effettiva, il comportamento non è definito.
7.2.1 Diagnostica del programma
7.2.1.1 La macro assert
Sinossi
1.
#include <assert.h> void assert(scalar expression);
Descrizione
2 La macro assert inserisce test diagnostici nei programmi; si espande in un'espressione vuota. Quando viene eseguito, se espressione (che deve avere un tipo scalare) è falsa (vale a dire, confronta uguale a 0), la macro assert scrive informazioni sulla chiamata particolare non riuscita (incluso il testo dell'argomento, il nome del file di origine, numero della riga di origine e nome della funzione che racchiude - questi ultimi sono rispettivamente i valori delle macro di preelaborazione
__FILE__
e__LINE__
e dell'identificatore__func__
) sul flusso di errori standard in un formato definito dall'implementazione. 165) Chiama quindi la funzione di interruzione.ritorna
3 La macro assert non restituisce alcun valore.
Ci sono tre ragioni principali per usare la funzione assert () sulla normale if else e printf
La funzione assert () viene utilizzata principalmente nella fase di debug, è noioso scrivere se altrimenti con un'istruzione printf ogni volta che si desidera verificare una condizione che potrebbe anche non farsi strada nel codice finale.
Nelle distribuzioni di software di grandi dimensioni, assert è molto utile in cui è possibile fare in modo che il compilatore ignori le istruzioni assert utilizzando la macro NDEBUG definita prima di collegare il file di intestazione per la funzione assert ().
assert () è utile quando si progetta una funzione o un codice e si vuole farsi un'idea di quali limiti il codice funzionerà e non funzionerà e infine includere un if per la valutazione fondamentalmente giocando con i presupposti.
È una funzione che interrompe l'esecuzione del programma se il valore che ha valutato è falso. Di solito è circondato da una macro in modo che non venga compilato nel binario risultante quando viene compilato con le impostazioni di rilascio.
È progettato per essere utilizzato per testare le ipotesi formulate. Per esempio:
void strcpy(char* dest, char* src){
//pointers shouldn't be null
assert(dest!=null);
assert(src!=null);
//copy string
while(*dest++ = *src++);
}
L'ideale che desideri è che puoi fare un errore nel tuo programma, come chiamare una funzione con argomenti non validi, e premi un'asserzione prima che segfault (o non funzioni come previsto)
Inoltre, è possibile utilizzarlo per verificare se l'allocazione dinamica ha avuto esito positivo.
Esempio di codice:
int ** p;
p = new int * [5]; // Dynamic array (size 5) of pointers to int
for (int i = 0; i < 5; ++i) {
p[i] = new int[3]; // Each i(ptr) is now pointing to a dynamic
// array (size 3) of actual int values
}
assert (p); // Check the dynamic allocation.
Simile a:
if (p == NULL) {
cout << "dynamic allocation failed" << endl;
exit(1);
}
new
genera un'eccezione in caso di errore di allocazione a meno che non specifichi nothrow
(cosa che non hai fatto qui). Inoltre, la tua formattazione è strana ed exit
è cattiva.
assert()
serve solo per eseguire il debug e sradicare cose che non dovrebbero mai, mai, mai accadere - molto prima che venga realizzata una build di rilascio.