2010-07-23 15 views
21

Stavo prendendo uno sguardo al the assert() reference page e sono rimasto bloccato mentre leggevo l'esempio:Sto fraintendendo l'uso di assert()?

/* assert example */ 
#include <stdio.h> 
#include <assert.h> 

int main() 
{ 
    FILE * datafile; 
    datafile=fopen ("file.dat","r"); 
    assert (datafile); 

    fclose (datafile); 

    return 0; 
} 

In questo esempio, affermano viene utilizzato per interrompere l'esecuzione del programma, se file di dati a confronto uguale a 0, il che accade quando la precedente chiamata a fopen non ha avuto successo.

Sono assolutamente d'accordo che se fopen() fallisce, assert() interromperà l'esecuzione. Comunque io sono preoccupato per la giustezza di questo esempio:

A mio parere assert() c'è da rilevare che i casi non può normalmente accadere (come passare un puntatore NULL ad una funzione il cui documentazione afferma è vietato).

In questo esempio, non riuscire ad aprire un file non è qualcosa che normalmente non può verificarsi. In effetti, posso vedere dozzine di ragioni per cui ciò fallirebbe. Il file non potrebbe esistere, il programma potrebbe essere eseguito senza i privilegi richiesti e così via.

avrei preferito fatto qualcosa di simile:

/* not longer an assert example */ 
#include <stdio.h> 
#include <assert.h> 

int main() 
{ 
    FILE * datafile; 
    datafile=fopen ("file.dat","r"); 

    if (datafile != NULL) 
    { 
    // Do something, whatever. 
    fclose (datafile); 
    } else 
    { 
    // Report the error somehow. 
    } 

    return 0; 
} 

è la mia comprensione di come assert() dovrebbe essere usato non è corretto?


MODIFICA E BUONE NOTIZIE!

Sembra che il sito indicato sia governato da persone rigorose. Ecco la mail che ho tornato da uno dei siti manutentore:

Ciao Julien, io sono d'accordo, il codice esempio è stato scelto male. È stato appena riscritto a qualcosa di più appropriato.

Mille grazie per segnalando questo, e mi dispiace per eventuali problemi questo potrebbe aver causato a voi voi.

Con i migliori saluti,

E l'esempio aggiornato:

/* assert example */ 
#include <stdio.h> 
#include <assert.h> 

void print_number(int* myInt) { 
    assert (myInt!=NULL); 
    printf ("%d\n",*myInt); 
} 

int main() 
{ 
    int a=10; 
    int * b = NULL; 
    int * c = NULL; 

    b=&a; 

    print_number (b); 
    print_number (c); 

    return 0; 
} 

Sono contento di vedere che alcune persone fanno il loro lavoro bene su Internet! ;)

+8

+1 Per riconoscere che questo è un cattivo esempio. +2 Per poi spedire i contatti del sito. –

+4

La tua comprensione è azzeccata. 'assert' è per errori di programmazione, non errori dell'utente. – GManNickG

+0

Ho rimosso il tag C++, poiché non c'è uno scrap di codice C++ nel post. – Puppy

risposta

13

Hai perfettamente ragione, signore. Questo è uno scarso utilizzo di assert.

+0

anzi, asserire dovrebbe essere solo l'ultima istanza alias collasso mondiale – RvdK

+2

Grazie per il feedback. Ho scritto alla pagina dei contatti per informarli del problema. Mi chiedo se lo aggiorneranno. – ereOn

+0

+1 per questo può essere una potenziale risposta ;-) – KedarX

1

notifica Minore: sarebbe meglio se si scrive ..

FILE * datafile = NULL; 

Inoltre, affermare funziona solo in modalità debug ... in modo che il metodo è migliore.

+0

Bene, questo non è il mio codice. E mentre di solito inizializzo le mie variabili locali, qui 'datafile' viene assegnato subito dopo la sua dichiarazione, quindi non ha molta importanza;) Buon punto sulla modalità di debug, non ci avevo nemmeno pensato. – ereOn

+0

Cosa ti fa dire che funziona solo in modalità di debug? –

+1

@Praveen: assert è una macro che fa qualcosa solo quando 'NDEBUG' non è definito. Quindi di solito in modalità di debug. – ereOn

2

Hai ragione.Come altre persone hanno già sottolineato, lo assert() sarà più che probabile compilato nella build di rilascio (ho visto persone forzare gli asseritori a lasciare la build di rilascio).

Volevo solo aggiungere una storia di orrore relativa a questa domanda che ho visto su un codice-base:

assert(do_something() == NO_ERR); 

Alcune persone non dovrebbe essere consentito di utilizzare una tastiera.

+1

Vero. Anche se dipende da cosa fa_qualcosa(). se do_something() è davvero do_complex_validation_that_system_state_is_valid() allora * potrebbe * essere ragionevole se non ha effetti collaterali – jcoder