Sì! Puoi eliminare main.
Disclaimer: Hai chiesto se fosse possibile, non se fosse necessario. Questa è una pessima idea totalmente non supportata. L'ho fatto io stesso, per ragioni per cui non entrerò, ma non lo raccomanderò. Il mio scopo non era quello di sbarazzarmi di main, ma può farlo anche.
I passaggi fondamentali sono i seguenti:
- Trova
crt0.c
nella directory sorgente CRT del compilatore.
- Aggiungi
crt0.c
al tuo progetto (una copia, non l'originale).
- Trova e rimuovi la chiamata al principale da
crt0.c
.
Compilare e collegare può essere difficile; Quanto difficile dipende da quale compilatore e da quale versione del compilatore.
Aggiunto
ho appena fatto con Visual Studio 2008, per cui qui sono i passaggi esatti si deve prendere per farlo funzionare con quel compilatore.
- Creare una nuova applicazione console C++ Win32 (fare clic su Avanti e selezionare
Empty Project
).
- Aggiungere un nuovo elemento .. File C++, ma denominarlo
crt0.c
(non .cpp).
- Copia il contenuto di
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\crt0.c
e incolla nello crt0.c
.
- Trova
mainret = _tmain(__argc, _targv, _tenviron);
e commentalo.
- Fare clic con il pulsante destro del mouse su
crt0.c
e selezionare Proprietà.
- Imposta C/C++ -> Generale -> Directory di inclusione aggiuntiva =
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src"
.
- Set C/C++ -> Preprocessore -> Definizioni del preprocessore =
_CRTBLD
.
- Fare clic su OK.
- Fare clic con il tasto destro del mouse sul nome del progetto e selezionare Proprietà.
- Imposta C/C++ -> Generazione codice -> Libreria di runtime =
Multi-threaded Debug (/MTd)
(*).
- Fare clic su OK.
- Aggiungere un nuovo elemento .. File C++, denominarlo in qualsiasi modo (
app.cpp
per questo esempio).
- Incollare il codice di seguito in
app.cpp
ed eseguirlo.
(*) Non è possibile utilizzare la DLL di runtime, è necessario collegare staticamente alla libreria di runtime.
#include <iostream>
class App
{
public: App()
{
std::cout << "Hello, World! I have no main!" << std::endl;
}
};
static App theApp;
Aggiunto
ho rimosso la chiamata uscita superfluo e la fascetta pubblicitaria sulla vita come penso che siamo tutti in grado di comprendere le conseguenze della rimozione principale.
Ultra Necro
Ho appena imbattuto in questa risposta e leggere sia esso e le obiezioni di John Dibling qui sotto. Era chiaro che non ho spiegato cosa fa la procedura sopra e perché questo rimuove completamente il main dal programma.
John afferma che "c'è sempre un main" nel CRT. Quelle parole non sono strettamente corrette, ma lo spirito dell'affermazione è. Main non è una funzione fornita dal CRT, devi aggiungerla tu stesso. La chiamata a quella funzione è nella funzione del punto di ingresso fornita da CRT.
Il punto di ingresso di ogni programma C/C++ è una funzione in un modulo denominato 'crt0'. Non sono sicuro che questa sia una convenzione o parte delle specifiche del linguaggio, ma ogni compilatore C/C++ che ho incontrato (che è molto) lo usa.Questa funzione fa fondamentalmente tre cose:
- inizializzare la CRT
- chiamata principale
- abbattere
Nell'esempio precedente, la chiamata viene _tmain ma che è un po 'di magia macro per consentire le varie forme che può avere "main", alcune delle quali sono specifiche per VS in questo caso.
L'operazione sopra descritta rimuove il modulo 'crt0' dal CRT e lo sostituisce con uno nuovo. Questo è il motivo per cui non è possibile utilizzare la DLL di runtime, esiste già una funzione in quella DLL con lo stesso nome del punto di ingresso di quello che stiamo aggiungendo (2). Quando si collega staticamente, il CRT è una raccolta di file .lib e il linker consente di ignorare completamente i moduli .lib. In questo caso un modulo con una sola funzione.
Il nostro nuovo programma contiene il CRT di serie, meno il suo modulo CRT0, ma con un modulo CRT0 di nostra creazione. Lì rimuoviamo la chiamata al main. Quindi non c'è main ovunque!
(2) Si potrebbe pensare di poter utilizzare la DLL di runtime rinominando la funzione del punto di ingresso nel file crt0.c e modificando il punto di ingresso nelle impostazioni del linker. Tuttavia, il compilatore non è al corrente della modifica del punto di ingresso e la DLL contiene un riferimento esterno a una funzione "principale" che non viene fornita, quindi non verrà compilata.
Interessante domanda. Non avevo mai pensato di avere un singolo oggetto globale. Come dici tu, cattiva pratica, ma comunque interessante. –
qualcosa come questo è implementato in MFC dove si ha istanza singola di 'CWinApp' – Andrey
@CwinApp, MFC fornisce main/winmain per te. Quindi, hai ancora una funzione main() in MFC. –