L’exécution du programme doit-elle commencer à partir de main, ou l’adresse de départ peut-elle être modifiée?
#include void fun(); #pragma startup fun int main() { printf("in main"); return 0; } void fun() { printf("in fun"); }
Ce programme imprime in fun
avant in main
.
La commande ‘#pragma’ est spécifiée dans la norme ANSI pour avoir un effet arbitraire défini par l’implémentation. Dans le préprocesseur GNU C, ‘#pragma’ tente d’abord de lancer le jeu ‘rogue’; si cela échoue, il essaie de lancer le jeu ‘bidouillage’; si cela échoue, il essaie de lancer GNU Emacs en affichant la tour de Hanoi; si cela échoue, une erreur fatale est signalée. Dans tous les cas, le prétraitement ne continue pas.
– Richard M. Stallman, Le préprocesseur GNU C, version 1.34
L’exécution du programme commence au code de démarrage ou “runtime”. Il s’agit généralement d’une routine d’assembleur appelée _start
ou similaire, située (sur les machines Unix) dans un fichier crt0.o
fourni avec le package du compilateur. Il effectue la configuration requirejse pour exécuter un exécutable C (par exemple, configurer stdin
, stdout
et stderr
, les vecteurs utilisés par atexit()
… pour C ++, il inclut également l’initialisation d’objects globaux, c’est-à-dire l’exécution de leurs constructeurs). Ce n’est qu’alors que le contrôle passe à main()
.
Comme le dit si bien la citation du début de ma réponse, ce que #pragma
fait est entièrement à la charge de votre compilateur. Vérifiez sa documentation. (Je suppose que votre pragma startup
– auquel il convient d’append un #
au passage – indique au runtime d’appeler d’abord fun()
…)
En ce qui concerne la norme ISO C, le point d’entrée d’un programme C est toujours main
(à moins qu’une fonctionnalité définie par l’implémentation ne soit utilisée pour le remplacer) pour une implémentation hébergée . Pour une “implémentation autonome” (généralement un système intégré, souvent sans système d’exploitation), le point d’entrée est défini par l’implémentation.
Les programmes C ne démarrent pas nécessairement à partir de main()
fonction main()
. Certains codes sont exécutés avant main()
qui met à zéro toutes les variables globales non initialisées et initialise les autres variables globales avec la valeur appropriée. Par exemple, considérons le code suivant:
int a; int b = 10; int main() { int c = a * b; return 0; }
Dans l’exemple de code ci-dessus, 0
et 10
sont atsortingbués à a et b
respectivement, avant l’exécution de la première ligne de main()
.
La directive #pragma
de définir le comportement défini par l’implémentation. Votre code avec #pragma
peut être compilé dans un compilateur mais ne peut pas être compilé dans un autre.