Skeptar schrieb:
Du hast zu 120% recht das ich davon kaum etwas verstehen :p
Aber trodzdem danke für den aufwand.
Es ist vielleicht einfacher zu verstehen, wenn du dran denkst, dass fast alles hier Makros sind. Außerdem kannst du im Kopf alle Unterstriche wegdenken, die sind bloß da, um Namenskollisionen zu verhindern. Danach ist das wie das Lesen von typischen Präprozessorcode, der aber eben nicht viel mit C oder C++ gemeinsam hat. Zum Lesen musst du dann fit sein und verstehen, was ifdef, define & Co. machen. Dann machst du das im Kopf nach. Beispielsweise der Fall, dass NDEBUG definiert ist (also wenn assert einfach übersprungen werden soll):
#if defined __cplusplus && __GNUC_PREREQ (2,95)
# define __ASSERT_VOID_CAST static_cast<void>
#else
# define __ASSERT_VOID_CAST (void)
#endif
/* void assert (int expression);
If NDEBUG is defined, do nothing.
If not, and EXPRESSION is zero, print an error message and abort. */
#ifdef NDEBUG
# define assert(expr) (__ASSERT_VOID_CAST (0))
Zeile 1 prüft, ob wir C++ machen. Falls ja, wird in Zeile 2 __ASSERT_VOID_CAST als ein C++-static_cast zu void definiert, falls nein (Zeile 3), dann machen wir wohl C und in Zeile 4 wird __ASSERT_VOID_CAST als ein C-Cast zu void definiert. Zeile 5 beendet den if-Block. Dann kommt ein Kommentar, der nochmal erklärt, was assert überhaupt macht. Dann wird in Zeile 12 geprüft, ob NDEBUG definiert ist. Falls ja, wird assert als (__ASSERT_VOID_CAST (0)) definiert. Das __ASSERT_VOID_CAST ist dabei das Makro für den Cast von oben*. Es wird also 0 zu void gecastet, was in beiden Sprachen einfach gar nichts macht.
Danach geht's weiter in der Art und Weise. Man muss eben Präprozessor lesen können.
*: Hier ist es nicht wichtig, aber man sollte noch erwähnen, dass der Präprozessor lazy evaluation benutzt:
#define FOO 5
#define BAR FOO
#undef FOO
#define FOO 6
BAR // 6, nicht 5