2016-06-09 5 views
5

consideri la coppia di funzioni di seguito:Come forzare l'inizializzazione di una variabile locale statica prima di main?

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

register_foo_ è una variabile globale, inizializzazione prima dllmain, il cui costruttore prende un lambda che fa riferimento ripetutamente il nome della funzione sopra letteralmente. Sarebbe bello se il codice di registrazione potesse spostarsi all'interno della funzione sopra per ridurre le possibilità di errore. Ho provato:

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

Se il codice precedente funziona, allora posso facilmente trasformarlo in una macro che fa uso di __FUNCNAME__. C'è un modo per forzare l'inizializzazione della variabile locale statica register_foo_ prima di dllmain?

+0

Se chiamando 'foo' non ha effetti collaterali indesiderati, si potrebbe chiamare all'inizio del' dllmain' – Praetorian

+0

Quindi, in pratica, vuoi chiamare una funzione prima di main? O mi sono confuso? – Galik

+0

@Praetorian Ciò che cerca di ottenere è il tracciamento automatico della funzione registrata. Quindi chiamare dllmain non funziona, dal momento che dovrò scrivere esplicitamente i nomi delle funzioni. –

risposta

1

Suppongo che si vuole raggiungere una sintassi simile a:

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

... e fare in modo che la piastra di riscaldamento sia autogenerata. Che in realtà è molto semplice da fare se si mettono il Register sopra la funzione, con l'aiuto di una dichiarazione:

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

funziona, grazie. –

0

No, non c'è. Questa è la tua risposta.

3

Le variabili statiche locali a una funzione (metodo) vengono inizializzate al primo utilizzo della funzione in cui si trovano. (Sono inizializzate a zero al caricamento del programma, quindi inizializzate "correttamente" tramite codice quando la funzione viene immessa per la prima volta .) Vedi lo answers to this question. Quindi il tuo movimento proposto di quel codice nella funzione cambia la semantica dell'inizializzazione e non funzionerà.

Il tuo codice originale funzionava, quindi quello che apparentemente volevi era spostare il codice all'interno della funzione in modo che fosse in qualche modo legato più vicino nella tua mente - o la mente di un lettore del codice - in modo che tu potessi vedere che il tuo il nome costante della stringa e il nome della funzione erano corretti. Forse anche per assicurarti che la registrazione sia stata fatta. E quindi quello che vuoi è realizzare SECCO.

Il tradizionale (e unico) modo per ottenere ciò consiste nell'utilizzare una macro del preprocessore che si espande nella chiamata di registrazione e nell'intestazione della funzione.

È proposto di utilizzare una macro da soli - ora ampliare la macro in modo che non solo genera la funzione di registrazione, ma anche l'intestazione di funzione.

+0

C'è un modo per fare ciò che voglio lavorare?Concettualmente, l'elenco dei nomi di funzioni è una costante di tempo di compilazione. –

+0

@CandyChiu - ha ampliato la mia risposta per rispondere alla sua domanda. – davidbak

+0

grazie. Ho upvoted la tua spiegazione, ma ho selezionato la risposta di Quentin perché ha pubblicato il codice. –

3

Questa esegue una funzione prima di main(), non so se funzionerà per dllmain():

#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'; 
} 

uscita:

func_before_main() 
main() 
+0

Un modo per farlo 'const int dummy = func_before_main();' senza scrivere esplicitamente 'func_before_main'? –

+0

@CandyChiu Probabilmente dipende da come appare la (orribile) MACRO che si desidera creare. Potrebbe essere parte di quello. – Galik

Problemi correlati