C ++ bestätigt die Implementierung in assert.h

8
%Vor%

Die Frage ist: Was ist für das "(void)" in Zeile 34 und was ist __assert?

    
Narek 14.03.2012, 11:39
quelle

4 Antworten

12

Schauen Sie sich diese Zeile an:

%Vor%

__assert ist eine Funktion, die eine Assertion-Nachricht, einen Dateinamen und eine Zeilennummer als Argumente akzeptiert. Im Grunde ist dies die Methode, die die Fehlermeldung ausgibt und das Programm beendet, wenn die Assertion fehlgeschlagen ist.

Sehen Sie sich dann die obige Makrodefinition an:

%Vor%

Er definiert das assert(EX) -Makro so, dass er zuerst den EX-Ausdruck und (wegen der Kurzschlussoperation des C ++ || -Operators) nur dann, wenn es fehlschlägt, die __assert -Funktion aufruft und die gescheiterte Assertionsausnahme als Zeichenfolge und die genaue Position des assert() -Methodenaufrufs in Ihren Quelldateien. Mit dieser Preprozessor-Trickserei erreicht die Assertion-Library das, wenn Sie in Ihrem Programm Folgendes eingeben:

%Vor%

und Ihre Assertion schlägt während des Programmlaufs fehl, erhalten Sie das detaillierte

%Vor%

Fehlermeldung, die Ihnen hilft, den genauen Speicherort der Assertion in Ihrem Code zu identifizieren.

Der (void) -Teil ist nur dafür da, dass der Compiler keine Warnungen über das ungenutzte Ergebnis des (EX) || 0 Ausdrucks ausgibt, siehe die anderen Antworten, die Jungs haben das gut erklärt.

Der verbleibende Präprozessor define NDEBUG wird verwendet, um die Generierung der Assertion während der gesamten Kompilierungszeit einzuschalten. Ihre resultierende ausführbare Datei wird kleiner und schneller sein.

    
buc 14.03.2012, 11:51
quelle
7

__assert ist Teil der Implementierung; in diesem Fall eine Funktion in der Bibliothek, die im Falle eines Assertionsfehlers aufgerufen wird. Und das (void) besteht einfach darin, Compiler-Warnungen über die nicht verwendeten Ergebnisse des || -Operators zu schließen.

    
James Kanze 14.03.2012 11:41
quelle
1

Es unterdrückt Compiler-Warnungen über nicht verwendete Werte oder Variablen.

Beachten Sie auch den Komma-Operator auf der rechten Seite, der beide Seiten von || etwas macht, das in bool konvertiert werden kann.

__assert ist eine interne Funktion, die vermutlich eine Nachricht druckt und das erforderliche Assertionsverhalten implementiert (d. h. Aufruf abort() ).

    
Kerrek SB 14.03.2012 11:41
quelle
1

Fast ...

Betrachte: assert( a == 0 ); Dies wird zu

erweitert

(void)((a == 0) || (__assert (#a == 0, __FILE__, __LINE__),0))

Wenn Sie den Ausdruck (x || y) haben - In diesem Fall werden sowohl x als auch y als bools ausgewertet. Wenn also 'a' zu 0 wird, wird die Definition von || sagt, um das nächste Bool in der Reihe zu versuchen, zB 'y'

Also - wenn Ihre Behauptung falsch ist, wird (__assert (#a == 0, __FILE__, __LINE__),0) ausgewertet, was bedeutet, dass __assert() aufgerufen wird.

Warum das (__assert (), 0) ?? __asset ist eine Funktion, die als void __assert() - naja ... die meiste Zeit definiert ist. siehe Ссылка für einen Satz assert () Makros - beachte das alles von ihnen am Ende eine Funktion aufrufen ...

Mit dem Komma-Operator können Sie zwei Dinge in der gleichen Anweisung tun, dh i++, j++ - aber denken Sie daran, dass ein Ausdruck zu einem Wert - in diesem Fall zu der "0" - ausgewertet werden muss Die gesamte Anweisung wird in (void)(0 || 0) ausgewertet, was ein gültiger Ausdruck ist. Als Nebeneffekt wird Ihr Ausdruck ausgewertet und möglicherweise eine Funktion aufgerufen.

Hinweis in (void)(0 || 0) Die erste 0 stammt von Ihrer fehlgeschlagenen Assertion. Dies kann zur Kompilierzeit erzeugt werden, wenn Ihre Assertion etwas auswertet, das der Compiler als Konstante erzeugen kann, oder einen Ausdruck, der ausgewertet wird, zB (void)((a == 0) || 0)

Beachten Sie das Komma ", 0" ist für wirklich pedantische Compiler - ich sehe es normalerweise nicht. Aber die (a || __assert()) ist sehr häufig. Sie könnten das Makro als

schreiben %Vor%     
user2913342 23.10.2013 21:58
quelle

Tags und Links