Come posso eseguire l'inizializzazione pre-principale in C/C++ con avr-gcc?

Come posso eseguire l'inizializzazione pre-principale in C/C++ con avr-gcc?

Puoi utilizzare constructor di GCC attributo per garantire che venga chiamato prima di main() :

void Init(void) __attribute__((constructor));
void Init(void) { /* code */ }  // This will always run before main()

Puoi abbreviare leggermente quanto sopra dando "inizializza" un tipo restituito e usandolo per inizializzare una variabile globale:

int initialize();
int dummy = initialize();

Tuttavia, devi stare attento con questo, lo standard non garantisce che l'inizializzazione di cui sopra (o quella per il tuo oggetto init) avvenga prima dell'esecuzione di main (3.6.2/3):

L'unica cosa che è garantita è che l'inizializzazione avrà luogo prima che venga mai utilizzato 'dummy'.

Un'opzione più invadente (se possibile) potrebbe essere quella di utilizzare "-D main=avr_main" nel tuo makefile. Puoi quindi aggiungere il tuo main come segue:

// Add a declaration for the main declared by the avr compiler.
int avr_main (int argc, const char * argv[]);  // Needs to match exactly

#undef main
int main (int argc, const char * argv[])
{
  initialize ();
  return avr_main (argc, argv);
}

Almeno qui hai la certezza che l'inizializzazione avverrà quando previsto.


Ecco un metodo alquanto malvagio per raggiungere questo obiettivo:

#include <stdio.h>

static int bar = 0;

int __real_main(int argc, char **argv);

int __wrap_main(int argc, char **argv)
{
    bar = 1;
    return __real_main(argc, argv);
}

int main(int argc, char **argv)
{
    printf("bar %d\n",bar);
    return 0;
}

Aggiungi quanto segue ai flag del linker:--wrap main

es.

gcc -Xlinker --wrap -Xlinker main a.c

Il linker sostituirà tutte le chiamate a main con chiamate a __wrap_main , vedi la pagina man di ld su --wrap