Eh bien, le titre dit tout.Est une fonction main() absolument indispensable pour un programme c. Je demande cela parce que j'étais en train de regarder le code du noyau de Linux,et je ne vois pas une fonction main ().
Réponses
Trop de publicités?Non, le C ISO norme stipule qu'un main
fonction n'est nécessaire que pour un environnement hébergé (tel qu'un avec l'OS sous-jacent).
Pour un autoportant environnement comme un système embarqué (ou un système d'exploitation lui-même), c'est la mise en œuvre définies. De C99 5.1.2
:
Deux environnements d'exécution sont définis: autonome et organisé. Dans les deux cas, le démarrage du programme se produit lorsqu'un désignée C la fonction est appelée par l'environnement d'exécution.
Dans un autoportant environnement (dont C l'exécution d'un programme peut avoir lieu sans l'avantage d'un système d'exploitation), le nom et le type de la fonction appelée au démarrage du programme sont définis par l'implémentation.
Comment Linux en lui-même commence, le point de départ pour le noyau Linux est start_kernel si, pour une image plus complète de l'ensemble du processus de démarrage, vous devez commencer ici.
Eh bien, non, mais ...
C99 spécifie qu' main()
est appelé dans l'environnement hébergé "au démarrage du programme", cependant, vous ne devez pas utiliser le C support d'exécution. Votre système d'exploitation exécute des fichiers d'image et de démarrer un programme à une adresse fournie par l'éditeur de liens.
Si vous êtes prêt à écrire votre programme pour se conformer au système d'exploitation, les exigences plutôt que de C99, vous pouvez le faire sans main(). Le plus moderne (et complexe), le système, même si, le plus de difficulté que vous aurez avec la bibliothèque C de faire des hypothèses que la norme d'exécution de démarrage est utilisé.
Voici un exemple pour Linux...
$ cat > nomain.S
.text
_start:
call iamnotmain
movl $0xfc, %eax
xorl %ebx, %ebx
int $0x80
.globl _start
$ cat > demo.c
void iamnotmain(void) {
static char s[] = "hello, world\n";
write(1, s, sizeof s);
}
$ as -o nomain.o nomain.S
$ cc -c demo.c
$ ld -static nomain.o demo.o -lc
$ ./a.out
hello, world
C'est sans doute pas un "C99 programme" maintenant, si, juste un "Linux" avec un objet module écrit en C.
Paxdiablo de répondre couvre deux des cas où vous ne rencontrerez pas d'un principal. Permettez-moi d'ajouter un couple de plus de:
- De nombreux plug-in de systèmes pour d'autres programmes (comme, par exemple, des navigateurs ou des éditeurs de texte ou autres) n'ont pas d'
main()
. - Windows les programmes écrits en C ont pas d'
main()
. (Ils ont unWinMain()
à la place.)
Les systèmes d'exploitation chargeur pour appeler un point d'entrée unique; dans le compilateur GNU, le point d'entrée est défini dans le crt0.o objet lié, le fichier de source pour ce qui est de l'assembleur fichier crt0.s - qui appelle main() après l'exécution de divers moment de l'exécution de la start-up de tâches (telles que l'établissement d'une pile, statique d'initialisation). Donc, lors de la construction d'un exécutable qui relie la valeur par défaut crt0.o, vous devez disposer d'une main(), sinon vous aurez une erreur de l'éditeur de liens depuis dans crt0.o() est un symbole non résolu.
Il serait possible (si un peu pervers et inutile) de modifier crt0.s pour appeler un autre point d'entrée. Assurez-vous de faire un tel objet fichier spécifique à votre projet, plutôt que de modifier la version par défaut, ou vous briser tous les de construire sur cette machine.
Le système d'exploitation lui-même a son propre C runtime start-up (qui seront appelés à partir du chargeur de démarrage), de sorte pouvez appeler n'importe quel point d'entrée qu'il souhaite. Je n'ai pas regardé la source de Linux, mais imaginez qu'il a son propre crt0.s qui permettront d'appel quel que soit le code C d'un point d'entrée.