2016-06-09 4 views
5

sich das Paar von Funktionen unter:Wie erzwinge die Initialisierung einer statischen lokalen Variablen vor dem Hauptterminal?

double MYAPI foo(double x) { 
    return x; 
} 
Register register_foo_([] { 
    return reg(&foo, "foo", ...); // function name repeated used 
}); 

register_foo_ ist eine globale Variable, bevor dllmain initialisiert, deren Konstruktor nimmt einen Lambda, die den Namen der Funktion darüber wörtlich wiederholt verweist. Es wäre großartig, wenn sich der Registrierungscode innerhalb der obigen Funktion bewegen könnte, um die Wahrscheinlichkeit eines Fehlers zu verringern. Ich habe versucht:

double MYAPI foo(double x) { 
    static Register register_foo_([] { 
      return reg(&foo, "foo", ...); // static local does not initialize before dllmain 
    }); 
    return x; 
} 

Wenn der obige Code funktioniert, dann kann ich es einfach in ein Makro verwandeln, die Verwendung von __FUNCNAME__ macht. Gibt es eine Möglichkeit, die Initialisierung der statischen lokalen Variablen register_foo_ vor dllmain zu erzwingen?

+0

Wenn Aufruf 'foo' keine unerwünschten Nebenwirkungen hat, können Sie es am Anfang nennen könnte von ' dllmain' – Praetorian

+0

Also im Grunde möchten Sie eine Funktion vor dem Haupt anrufen? Oder bin ich verwirrt worden? – Galik

+0

@Praetorian Was dies zu erreichen versucht, wird automatisch die registrierte Funktion zu verfolgen. Das Aufrufen von Dllmain funktioniert nicht, da ich die Funktionsnamen explizit schreiben muss. –

Antwort

1

Ich nehme an, Sie, um eine Syntax ähnlich erreichen wollen:

DEFINE_FUNC(void, foo, (double x)) { 
    return x; 
} 

... und lassen Sie das Muster automatisch generieren. Das ist eigentlich sehr einfach zu tun, wenn Sie die Register über die Funktion bringen, mit Hilfe einer Erklärung:

#define DEFINE_FUNC(Ret, name, args) \ 
    Ret name args;      \ 
    Register register_##name##_([] { \ 
     return reg(&name, #name, ...); \ 
    });        \ 
    Ret name args 
+0

das funktioniert, danke. –

0

Nein, gibt es nicht. Das ist deine Antwort.

3

Statische Variablen, die für eine Funktion (Methode) lokal sind, werden bei der ersten Verwendung der Funktion initialisiert. (Sie werden beim Programmstart auf Null initialisiert und beim ersten Aufruf der Funktion "richtig" über Code initialisiert) .) Siehe die answers to this question. Ihre vorgeschlagene Bewegung dieses Codes in die Funktion ändert also die Semantik der Initialisierung und wird nicht funktionieren.

Ihr ursprünglicher Code funktionierte, also was Sie anscheinend wollten, war, den Code innerhalb der Funktion zu verschieben, so dass er irgendwie in Ihrem Verstand - oder dem Verstand eines Lesers des Codes - näher zusammengebunden wurde, so dass Sie das sehen konnten String-Konstantenname und Funktionsname waren richtig. Vielleicht auch, damit Sie sicherstellen können, dass die Registrierung durchgeführt wurde. Und was Sie wollen, ist DRY zu erreichen.

Die traditionelle (und einzige) Weg, dies zu tun ist durch einen Präprozessormakro verwenden, die die Registrierung Aufruf und Funktionskopf expandiert in.

Sie vorgeschlagen, einen Makro selbst mit - jetzt das Makro erweitern, so dass es nicht nur die Funktion Registrierung erzeugt aber auch der Funktionskopf.

+0

Gibt es eine Möglichkeit zu machen, was ich will?Konzeptionell ist die Liste der Funktionsnamen eine Kompilierzeitkonstante. –

+0

@CandyChiu - erweiterte meine Antwort auf Ihre Frage zu beantworten. – davidbak

+0

danke. Ich habe deine Erklärung aufgestockt, aber ich habe Quentins Antwort ausgewählt, weil er Code gepostet hat. –

3

Diese Funktion vor main() läuft, nicht sicher, ob es für dllmain() arbeiten:

#include <iostream> 

int func_before_main() 
{ 
    std::cout << "func_before_main()" << '\n'; 
    // do before main stuff 
    return 0; 
} 

const int dummy = func_before_main(); 

int main() 
{ 
    std::cout << "main()" << '\n'; 
} 

Ausgang:

func_before_main() 
main() 
+0

Wie kann man dies tun? Const int dummy = func_before_main(); 'ohne' func_before_main' explizit auszugeben? –

+0

@CandyChiu Möglicherweise abhängig davon, was das (schreckliche) MACRO, das Sie erstellen möchten, aussieht. Es könnte ein Teil davon sein. – Galik

Verwandte Themen