2010-07-23 9 views
21

ich einen Blick auf the assert() reference page nehmen und ich stecken geblieben, während ich das gegebene Beispiel lesen:Missverstehe ich die Verwendung von 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 diesem Beispiel behaupten wird verwendet, um die Programmausführung abzubrechen, wenn Daten-Datei gleich 0 vergleicht, was passiert, wenn der vorherige Aufruf von fopen nicht erfolgreich war.

Ich bin völlig einverstanden, dass, wenn fopen() ausfällt, assert() Ausführung abbrechen wird. Jedoch habe ich besorgt über die Richtigkeit dieses Beispiels bin:

Meiner Meinung nach assert() gibt es Fälle zu erkennen, dass normalerweise nicht passieren (wie ein NULL Zeiger auf eine Funktion, deren Dokumentation vorbei besagt, es ist verboten).

In diesem Beispiel ist es nicht möglich, nicht normal zu öffnen. In der Tat kann ich Dutzende von Gründen sehen, warum dies fehlschlagen würde. Die Datei konnte nicht existieren, das Programm konnte ohne die erforderlichen Berechtigungen ausgeführt werden und so weiter.

Ich würde lieber getan haben, so etwas wie:

/* 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; 
} 

Ist mein Verständnis davon, wie assert() sollte falsch verwendet werden?


Bearbeiten und gute Nachrichten!

Es scheint, dass die genannte Website von rigorosen Menschen regiert wird. Hier ist die Post, die ich von einem der Website Maintainer zurück bekam:

Hallo Julien, ich muss zustimmen, die Beispielcode war schlecht gewählt. Es hat jetzt nur etwas umgeschrieben passender.

Vielen Dank für diesen Hinweis, und entschuldigen uns für etwaige Unannehmlichkeiten dies Sie verursacht haben.

Mit freundlichen Grüßen,

Und das aktualisierte Beispiel:

/* 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; 
} 

Froh, dass einige Leute über das Internet ihre Arbeit gut zu tun, um zu sehen! ;)

+8

+1 Um zu erkennen, dass dies ein schlechtes Beispiel ist. +2 Für das Versenden der Site-Kontakte. –

+4

Ihr Verständnis ist genau richtig. 'assert' steht für Programmierfehler, nicht für Benutzerfehler. – GManNickG

+0

Ich habe das C++ - Tag entfernt, da es im Beitrag keinen C++ - Code mehr gibt. – Puppy

Antwort

13

Sie haben vollkommen Recht, Sir. Dies ist eine schlechte Verwendung von assert.

+0

in der Tat, sollte behaupten, nur letzte Instanz sein alias Weltkollaps – RvdK

+2

Danke für die Rückmeldung. Ich habe auf die Kontaktseite geschrieben, um sie über das Problem zu informieren. Ich frage mich, ob sie es aktualisieren werden. – ereOn

+0

+1 für das kann eine mögliche Antwort sein ;-) – KedarX

1

Minor Benachrichtigung: Es wäre besser, wenn Sie schreiben ..

FILE * datafile = NULL; 

Auch behaupten funktioniert nur im Debug-Modus ... so Ihre Methode ist besser.

+0

Nun, das ist nicht mein Code. Und während ich normalerweise meine lokalen Variablen initialisiere, wird 'Datendatei' direkt nach der Deklaration zugewiesen, also ist es nicht wirklich wichtig;) Guter Punkt über den Debug-Modus, ich habe nicht einmal darüber nachgedacht. – ereOn

+0

Was sagt Sie, es funktioniert nur im Debug-Modus? –

+1

@ Praveen: assert ist ein Makro, das nur etwas tut, wenn 'NDEBUG' nicht definiert ist. Also normalerweise im Debug-Modus. – ereOn

2

Sie haben Recht.Wie andere Leute bereits darauf hingewiesen haben, wird assert() mehr als wahrscheinlich im Release-Build kompiliert werden (ich habe gesehen, dass Leute die Behauptungen zwingen, für den Release-Build übrig zu bleiben).

Ich wollte nur eine Horrorgeschichte auf diese Frage im Zusammenhang hinzufügen, dass ich auf einer Code-Basis gesehen habe:

assert(do_something() == NO_ERR); 

Einige Leute nicht eine Tastatur verwenden erlaubt sein sollen.

+1

Wahr. Obwohl es darauf ankommt, was do_something() tut. Wenn do_something() wirklich do_complex_validation_that_system_state_is_valid() ist, dann könnte es * sinnvoll sein, wenn es keine Nebenwirkungen hat – jcoder