atexit mit templates im selfmade?
-
Hi,
atexit ist ja schon ne feine sache, aber ich möchte es gerne auch selber verstehenw as da abläuft

Vorallem was micht stört, man kann an den übergebenen Funktionspointern keine Parameter übergeben

Daher dachte ich, ob dies mit Templatesmöglich ist, aber ich finde keine guten Denkansätze

Hat jemand eine Idee?
-
Nein, du kannst der Funktion keine Parameter mitgeben.
Du könntest die Kommunikation mit der Funktion über ein globales Objekt steuern.Du kannst atexit eine Funktion übergeben die ihrem Prototyp entspricht, eine Template-Funktion die diesem entspricht kannst du auch verwenden.
In aller Kürze: atexit hat intern eine queue die alle exit-handler speichert und bei Beenden diese der Reihe nach aufruft.
-
Du könnest ein Trampolin mit Nicht-Typ-Parametern verbauen... das sollt gehen.
-
atexit schrieb:
Denkansätze
Einer wäre
void realExitHandler(int A, int B) { std::cout << A << " " << B << std::endl; } template <int Param1, int Param2> void yourExitProxy() { realExitHandler(Param1, Param2); } // ... atexit(yourExitProxy<42, 23>); atexit(yourExitProxy<23, 42>);
-
hmn, aber es gibt keine möglichkeit ein atexit selber zu coden? mich würde sehr interessieren wie das intern alles abläuft

@tommie-lie
ey das ist ein super denkansatz für parameterübergabe danke!
-
Doch das kannst du und sogar sehr einfach spendier deinem Exit-Handler-System einen Einstiegspunkt mit einem Prototyp void(*)(), dann kannst du ihn einfach in atexit() einhängen und er wird zum richtig Zeitpunkt aufgerufen

Wenn du an das Buch Modern C++ Design kommen kannst, schau dir da mal das Kapitel über Singletons an, für ein Singleton-Pattern wird das da gemacht

-
atexit schrieb:
hmn, aber es gibt keine möglichkeit ein atexit selber zu coden?
Doch, atexit() ist nicht sonderlich komplex, es besteht beim GCC nur aus dem Aufruf einer compilerinternen Funktion.
atexit schrieb:
mich würde sehr interessieren wie das intern alles abläuft

Beim return von main() wird die glibc-Funktion exit() aufgerufen. Diese ruft der Reihe nach die Funktionen einer Liste auf. In diese Liste kannst du mit atexit() neue Funktionszeiger einfügen. Parameter funktionieren deshalb nicht, weil sowohl atexit(), als auch (viel wichtiger) exit() Bibliotheksfunktionen sind, die nichts über deinen Code wissen können. Es gibt in dieser Infrastruktur (der vom gcc) keine Möglichkeit, Parameter zu übergeben. Woher sollte exit() wissen, wie der Parameter zu lauten hat oder gar daß die Funktion einen Parameter hat?
Eine Lösung wäre nur das Umkrempeln der Infrastruktur hin zu template-basierten (und somit teilweise code-aware) Funktionen, womit das Ganze nicht mehr mit einem C-Compiler benutzbar ist (und exit() ist eine stdlib-Funktion).
Überhaupt hat meiner Meinung nach atexit() nichts in einem C++-Programm zu suchen (generell haben alle alten C-Header nichts in einem C++-Programm zu suchen). Die C++-Lösung dafür wäre eine Finalizer-Klasse, die in main() lokal erzeugt wird. Beim Aufräumen des (für dein Programm) äußersten Stack-Frames wird der Destruktor dieses Objektes aufgerufen und kann erledigen, was zu erledigen ist. Das Benötigen von globalen (zustandsunabhängigen) Funktionen zum Aufräumen deutet aber für mich auf einen Designfehler hin. Das ist auch ein Grund, warum es in C++ kein try..finally gibt: Es ist normalerweise einfach nicht notwendig. Was hast du denn in deinen Funktionen vor?lolz schrieb:
Wenn du an das Buch Modern C++ Design kommen kannst, schau dir da mal das Kapitel über Singletons an, für ein Singleton-Pattern wird das da gemacht
Uargs, was ist denn daran "modern"? Solche Techniken gehörne auf die dunkle Seite der Macht und sollten auch tunlichst dort bleiben.
Diverse Edits: Knoten im Finger.
-
tommie-lie schrieb:
lolz schrieb:
Wenn du an das Buch Modern C++ Design kommen kannst, schau dir da mal das Kapitel über Singletons an, für ein Singleton-Pattern wird das da gemacht
Uargs, was ist denn daran "modern"? Solche Techniken gehörne auf die dunkle Seite der Macht und sollten auch tunlichst dort bleiben.
Ich gehe mal in deinem Interresse davon aus, dass du dich auf das Singleton-Pattern im Buch beziehst, wo das Anwendung findet, ansonst wäre das ja ein Eigentor..
-
lolz schrieb:
tommie-lie schrieb:
lolz schrieb:
Wenn du an das Buch Modern C++ Design kommen kannst, schau dir da mal das Kapitel über Singletons an, für ein Singleton-Pattern wird das da gemacht
Uargs, was ist denn daran "modern"? Solche Techniken gehörne auf die dunkle Seite der Macht und sollten auch tunlichst dort bleiben.
Ich gehe mal in deinem Interresse davon aus, dass du dich auf das Singleton-Pattern im Buch beziehst, wo das Anwendung findet, ansonst wäre das ja ein Eigentor..
Nein, ich kenne das Buch nicht und beziehe mich auf die Benutzung von atexit() in (angeblich) modernem C++-Code.
Bei einfach gehaltenen Singletons beteht in der Tat das Problem, daß Ressourcen (sofern es nicht aussschließlich Speicher- oder Dateisystem-Ressourcen sind, die heutzutage vom Betriebssystem bei Prozessende selbst freigegeben werden) nicht freigegeben werden, aber es gibt auch fortschrittlichere Singleton-Implementierungen, die das vom Singleton verwaltete Objekt wieder freigeben, auch wenn es auf dem Heap lebt. Allein hier wird eine Methode genannt, in den Untiefen von CodeGuru findet man auch irgendwo eine Implementierung mittels einem smart pointer, der aufräumt.
-
Mir erschließt sich der Sinn der Implementierung in dem Artikel nicht wirklich, da ein Meyers-Singleton das gleiche, nur einfacher, tut.
Du kennst das Singleton-Pattern aus dem Buch Modern C++ Design gar nicht und kennst somit auch nicht die Design-Ziele dieses Patterns woher willst du also wissen, ob atexit() da nicht der einzige standardisierte Weg für die Implementierung in C++ ist?
-
lolz schrieb:
Du kennst das Singleton-Pattern aus dem Buch Modern C++ Design gar nicht und kennst somit auch nicht die Design-Ziele dieses Patterns woher willst du also wissen, ob atexit() da nicht der einzige standardisierte Weg für die Implementierung in C++ ist?
atexit() ist nur periphär Teil von C++ und mir ist kein Beispiel bekannt, das atexit() wirklich notwendig macht, deswegen bin ich der Meinung, daß atexit() in C++ nicht benutzt werden sollte. Wenn du ein Beispiel kennst, daß die Verwendung von atexit() unumgänglich macht, kannst du mich gerne vom Gegenteil überzeugen. C++-Code, der C-Konstrukte verwendet, nenne ich erstmal nicht modern, bis mir nichts besseres einfällt.
Klar ist mir, daß man mit atexit() teilweise Abkürzungen gehen kann, aber das kann ich auch durch sprintf() anstatt stringstreams, um eine Zahl in einen String zu konvertieren, besser ist sprintf() deswegen trotzdem nicht.