2012-06-05 11 views
30

Powiel możliwe:
Is main() really start of a C++ program?wywołać funkcję przed głównym

można nazwać moją funkcję przed uruchomieniem programu? Jak mogę to wykonać w C++ lub C?

+16

Czy istnieje powód, nie można po prostu od razu nawiązać połączenie po wprowadzeniu main(), ale przed żadnym z innym kodem wykonuje? Dlaczego pre-main() jest wymaganiem? – Omaha

+3

dlaczego nie wywołać tej funkcji na początku głównym? –

+3

Co takiego chcesz zrobić? Jeśli dalej wyjaśnisz swój faktyczny problem, możesz uzyskać sugestie dotyczące projektu (a nie techniki). Chociaż możesz zrobić to, o co prosisz, przemyślałbym projekt, który zależy od tego. –

Odpowiedz

38

Możesz mieć zmienną globalną lub członka klasy static.

1) static członkiem klasy

//BeforeMain.h 
class BeforeMain 
{ 
    static bool foo; 
}; 

//BeforeMain.cpp 
#include "BeforeMain.h" 
bool BeforeMain::foo = foo(); 

2) zmienna globalna

bool b = foo(); 
int main() 
{ 
} 

Uwaga ten link - Mirror of http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14/proposed alternative - wysłane przez Lundin.

+4

Uwaga: sama "klasa" jest tutaj fałszywa, wystarczy zbudowanie globalnego (cokolwiek). –

+3

Po prostu bądź świadomy [tego subtelnego błędu] (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14). Wywoływana funkcja nie może być zależna od jakichkolwiek zasobów statycznych. Powinieneś napisać to tak, jakbyś napisał funkcję ponownego wejścia. – Lundin

+0

Uważam, że jest to technicznie niepoprawne. AFAIR funkcja nie musi być wywoływana przed 'głównym' i może być opóźniona aż do 'b' jest potrzebna. A może po prostu obserwowalne państwo musiało być takie samo. – Pubby

25

W C++ jest prosta metoda: użyć konstruktora obiektu globalnego.

class StartUp 
{ 
public: 
    StartUp() 
    { foo(); } 
}; 

StartUp startup; // A global instance 

int main() 
{ 
    ... 
} 

Dzieje się tak, ponieważ obiekt globalny został skonstruowany przed uruchomieniem main(). Jak zauważył Lundin, należy zwrócić uwagę na static initialization order fiasco.

+0

Jakakolwiek część inicjalizacji, tak naprawdę, łącznie z argumentami przekazywanymi do konstruktora. –

+4

Po prostu bądź świadomy [tego subtelnego błędu] (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14). Wywoływana funkcja nie może być zależna od jakichkolwiek zasobów statycznych. Powinieneś napisać to tak, jakbyś napisał funkcję ponownego wejścia. – Lundin

11

W języku C++ jest to możliwe, np.

static int dummy = (some_function(), 0); 

int main() {} 

W C nie jest to dozwolone, ponieważ inicjalizatory obiektów o statycznym czas przechowywania musi być stała wyrażeń.

+0

W C nie ma sposobu? Tylko w C++? – Nick

+0

@Nick: tak, o ile wiem. –

+2

@ CharlesBailey: Możesz również sprawić, żeby działał w C: 'static size_t dummy = sizeof (some_function(), 0);' – Nawaz

14

przypadku korzystania gcc i g++ kompilatorów to może być wykonane za pomocą __attribute__((constructor))

np ::
GCC (C) ::

#include <stdio.h> 

void beforeMain (void) __attribute__((constructor)); 

void beforeMain (void) 
{ 
    printf ("\nbefore main\n"); 
} 

int main() 
{ 
printf ("\ninside main \n"); 
return 0; 
} 

w g ++ (C++) ::

#include <iostream> 
using namespace std; 
void beforeMain (void) __attribute__((constructor)); 

void beforeMain (void) 
{ 
    cout<<"\nbefore main\n"; 
} 

int main() 
{ 
    cout<<"\ninside main \n"; 
    return 0; 
} 
+7

Poza tym, że nie jest to C ani C++, jest to niestandardowe rozszerzenie GCC. – Lundin

+0

Miałem potrzebę wcześniejszego wywołania funkcji "void" przed serwerem głównym i próbowałem zaadaptować tę odpowiedź, ale ona się zawiesiła. Testowałem na cpp.sh, a także jako szef kuchni: ten sam wynik w obu przypadkach. Jeśli używam printf zamiast cout, nie ma awarii. Każdy pomysł, dlaczego? – StoneThrow

2

Proponuję odesłać ten link ..

http://bhushanverma.blogspot.in/2010/09/how-to-call-function-before-main-and.html

Dla kompilatora GCC na Linux/Solaris:

#include 

void my_ctor (void) __attribute__ ((constructor)); 
void my_dtor (void) __attribute__ ((destructor)); 

void 
my_ctor (void) 
{ 
printf ("hello before main()\n"); 
} 

void 
my_dtor (void) 
{ 
printf ("bye after main()\n"); 
} 

int 
main (void) 
{ 
printf ("hello\n"); 
return 0; 
} 

$gcc main.c 
$./a.out 
hello before main() 
hello 
bye after main()