Alternative zu initialization
-
Hallo,
in Delphi / ObjectPascal gibt es in einer Unit (sowas wie eine Header) einen interface, implementation, initialization und einen finalization Teil.
Die ersten Beiden sind selbsterklärend. Mir geht es um den Initialization Teil. Die dort angegebenen Funktionen werden ausgeführt, sobald die Unit geladen wird; also noch vor dem Start des eigentlichen Programms.Ich habe daraufhin eine vergleichbare Sache in C/C++ gesucht. Dabei bin ich auf die Compiler-Direktive "#pragma startup" gestoßen. Diese will mein Visaul Studio 2008 aber nicht so recht akzeptieren.
Weiß jemand wieso, oder kann mir sogar eine bessere Lösung sagen? Die einzige die mir einfallen würde, wäre dass ich meinen Code in einer DLL schreibe und die gewünschten Funktionen eben beim Laden der DLL ausführe ...
-
FrEEzE2046 schrieb:
Ich habe daraufhin eine vergleichbare Sache in C/C++ gesucht.
in c++ gibts 'konstruktoren', mit denen könnteste sowas machen. in C tut sich nix automatisch.
-
+fricky schrieb:
[in c++ gibts 'konstruktoren', mit denen könnteste sowas machen. in C tut sich nix automatisch.
Konstruktoren gibt es in Delphi auch ^^
Ja, auch eine Möglichkeit. Aber was ist mir angesprochener Compiler-Direktive?
-
du kannst alle deine funktionen in eine funktion all_my_functions
reinpacken und dann einen startup-code generieren:int main() { all_my_functions(); return 0; }
-
funktionatOr schrieb:
du kannst alle deine funktionen in eine funktion all_my_functions
reinpacken und dann einen startup-code generieren:int main() { all_my_functions(); return 0; }
Es geht eigentlich um eine normale Header-Datei, die beim einbinden gewissen Code ausführt. Diese besitzt logischerweise auch keine main Funktion.
-
FrEEzE2046 schrieb:
Aber was ist mir angesprochener Compiler-Direktive?
musste mal gucken, ob dein compiler das #pragma unterstützt. der von VS kanns (glaube ich) nicht.
-
Ich glaube das ist allgemein mit ANSI C nicht möglich. Mit Compilererweiterungen geht das aber. Der GCC bietet dafür das constructor/destructor Attribut an: http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Function-Attributes.html#Function-Attributes
-
FrEEzE2046 schrieb:
Es geht eigentlich um eine normale Header-Datei, die beim einbinden gewissen Code ausführt.
was meinst du mit 'beim einbinden'? code wird ja erst beim starten des programms ausgeführt.
-
+fricky schrieb:
FrEEzE2046 schrieb:
Es geht eigentlich um eine normale Header-Datei, die beim einbinden gewissen Code ausführt.
was meinst du mit 'beim einbinden'? code wird ja erst beim starten des programms ausgeführt.
Das ist mir auch klar. Ich meine - wie gesagt - vor dem Starten des Programms.
-
FrEEzE2046 schrieb:
Das ist mir auch klar. Ich meine - wie gesagt - vor dem Starten des Programms.
du meinst 'vor dem aufruf der main-funktion'. das kannste mit 'normalem' C nicht machen. wozu auch?
-
FrEEzE2046 schrieb:
Das ist mir auch klar. Ich meine - wie gesagt - vor dem Starten des Programms.
Das gibt es in C zum Glück nicht, denn es ist unnütz und würde nur Probleme verursachen. Was soll denn z.B. passieren, wenn sich mehrere Units von ihrem Initialization-Teil aus gegenseitig aufrufen? In welcher Reihenfolge soll das passieren? Eine von den Units würde dann schon verwendet werden, obwohl sie noch gar nicht initialisiert wurde, mit eventuell katastrophalen Folgen.
Wie fricky oben schon gesagt hat: In C++ ließ sich so eine Initialisierung mit Konstruktoren machen. Aber das führte dann auch zu genau dem Problem ("static initialization order fiasco").
-
namespace invader schrieb:
Das gibt es in C zum Glück nicht, denn es ist unnütz und würde nur Probleme verursachen.
Ich habe es bei einer Server-Applikation gebraucht. Im Initialization Teil wird die Server-Klasse hochgezogen und globale (für alle Client`s geltende) Variablen (UserCount, CListing etc.) gesetzt.
Innerhalb der Klasse bekommt jeder Client der auf die CoClass zugreift natürlich eine eigene Instanz derer.
-
Das ist ja toll, aber du kommst trotzdem um sowas wie
int main() { all_my_functions(); return 0; }
nicht drum herum.
-
namespace invader schrieb:
Wie fricky oben schon gesagt hat: In C++ ließ sich so eine Initialisierung mit Konstruktoren machen. Aber das führte dann auch zu genau dem Problem ("static initialization order fiasco").
Wo ist das Problem?
SomeCrazyType & getCrazyTypeInstance() { static SomeCrazyType instance; return instance; }
-
Das läuft dann aber nicht vor der main(), sondern erst, wenn jemand getCrazyTypeInstance() aufruft. Dafür braucht man kein C++.
Oder was meinst du?
-
namespace invader schrieb:
Das läuft dann aber nicht vor der main(), sondern erst, wenn jemand getCrazyTypeInstance() aufruft. Dafür braucht man kein C++.
Oder was meinst du?
Ich meine, dass es dann initialisert wird, wenn es das erste mal gebraucht wird. Zum Beispiel zur Konstruktion anderer globaler Objekte. Vorher ist es wohl auch überflüssig.
Und nein, in C geht es nicht. Die Konstruktion oben ist zwar kein Thema, aber man kann nicht, wie in C++, den Nutzen daraus ziehen.
-
Tachyon schrieb:
Und nein, in C geht es nicht. Die Konstruktion oben ist zwar kein Thema, aber man kann nicht, wie in C++, den Nutzen daraus ziehen.
welchen nutzen meinst du? in c kannste doch auch eine funktion schreiben, die in abhängigkeit von einem statischen flag eine struct initialisiert und dieselbe immer zurückgibt.
-
namespace invader schrieb:
Das gibt es in C zum Glück nicht, denn es ist unnütz und würde nur Probleme verursachen.
Unnütz ist es sicher nicht. Man kann damit so etwas wie Klassenkonstruktoren realisieren. Die Gefahr von Rekursion besteht bei der initialisierung von Hand (mindestens) genauso.
-
+fricky schrieb:
Tachyon schrieb:
Und nein, in C geht es nicht. Die Konstruktion oben ist zwar kein Thema, aber man kann nicht, wie in C++, den Nutzen daraus ziehen.
welchen nutzen meinst du? in c kannste doch auch eine funktion schreiben, die in abhängigkeit von einem statischen flag eine struct initialisiert und dieselbe immer zurückgibt.
Sagte ich ja auch. Aber Trigger dafür kann in C erst nach dem Eintritt in main() kommen...
-
Konfusius schrieb:
Die Gefahr von Rekursion besteht bei der initialisierung von Hand (mindestens) genauso.
Wenn man bei der Initialisierung von Hand eine Endlosrekursion baut, merkt man das aber, sobald man es ausprobiert. Im Gegensatz zu dem Glücksspiel von Konstruktoraufrufen bei globalen C++-Objekten.