Fonction main et liaison externe
Le
candide
Bonjour,
Je lis dans Plauger, "The standard C library", page 2 :
"A library object module should contain no definition of the the
function main with external linkage."
et il continue en disant :
"A programmer is unlikely to reuse code that insists on taking control
at program startup."
Je veux bien comprendre le deuxième point. Ce que je ne comprends pas
c'est le "with external linkage" dans le premier extrait. Dois-je
comprendre que l'énoncé suivant
"A library object module may contain a definition of the the function
main with _internal_ linkage"
est acceptable ? J'aurais le droit de définir main comme ceci :
static int main(void)
{
/* bla bla */
return 0;
}
?
J'ai essayé et gcc me renvoie un warning et Harbison & Steele dit :
"All C programs must define a single _external_ function named main"
(souligné par moi).
Et si on peut faire ainsi, quel en est l'intérêt "concret"
(i.e. dans quelles circonstances a-t-on besoin de procéder ainsi) ?
Merci.
Je lis dans Plauger, "The standard C library", page 2 :
"A library object module should contain no definition of the the
function main with external linkage."
et il continue en disant :
"A programmer is unlikely to reuse code that insists on taking control
at program startup."
Je veux bien comprendre le deuxième point. Ce que je ne comprends pas
c'est le "with external linkage" dans le premier extrait. Dois-je
comprendre que l'énoncé suivant
"A library object module may contain a definition of the the function
main with _internal_ linkage"
est acceptable ? J'aurais le droit de définir main comme ceci :
static int main(void)
{
/* bla bla */
return 0;
}
?
J'ai essayé et gcc me renvoie un warning et Harbison & Steele dit :
"All C programs must define a single _external_ function named main"
(souligné par moi).
Et si on peut faire ainsi, quel en est l'intérêt "concret"
(i.e. dans quelles circonstances a-t-on besoin de procéder ainsi) ?
Merci.

Poser une question


Je pense que oui (mais je n'y mettrais pas ma main au feu).
Tout seul dans une unité, notons que cela n'aurait pas beaucoup de sens.
Donc je suppose que cette fonction est accompagné d'autre code, qui
utiliserait cette fonction main() à liaison interne (par appel ou en gardant
un pointeur dans un objet statique ou alloué).
De plus, pour un environnement hébergé, tu devrais évidemment avoir dans une
_autre_ unité une définition de main avec liaison externe, de manière à
satisfaire la liaison qu'y réalise la bibliothèque système.
Jusque là, tout le monde semble assez d'accord, non ?
(le "external" auquel se réfère H&B signifie le main() avec liaison
externe).
Le seul intérêt que je vois à ce genre de manipulation, ce pourrait être de
pouvoir tester dans une unité un fonctionnemnt particulier (par exemple un
appel récursif à main), tout en gardant le contrôle du programme dans une
autre unité, non destinée à figurer dans le programme final, où il y aurait
le main effectif.
Un autre utilité (avec le "static" devant main qui serait effaçable par
macro), ce serait pour mettre un code de test dans une unité ; avec le
static effacé, on pourrait lier l'unité avec la bibliothèque standard et
obtenir un programme de test. Cela pourrait avoir l'aspect suivant
int mafonction() { /* ... */ }
#ifndef TEST
static
#endif
int main(void) { /* code de test */ }
Cependant, on a plutôt l'habitude d'écrire
#ifndef TEST
static
int main(void) { /* code de test */ }
#endif
qui a l'avantage de produire un module plus petit.
Antoine
"évidemment" : pour moi, ça n'a rien d'évident
OK, je n'ai pas compris tout de suite. Alors donc
#include
static int main (void)
{
printf("bonjour !n");
return 0;
}
me donne :
0.c:4: attention : «main" is normally a non-static function
0.c:4: attention : «main" defined but not used
/usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib/crt1.o: In function
`_start':
(.text+0x18): undefined reference to `main'
collect2: ld a retourné 1 code d'état d'exécution
Donc, il faudrait "deux" fonctions main, ça fait bizarre.
Je n'ai trouvé qu'un seul exemple sur Google codesearch :
#if !APR_HAS_THREADS
static int main(void)
{
printf("This test requires APR thread support.n");
return 0;
}
/* code omis */
#else /* APR_HAS_THREADS */
int main(void)
{
/* code omis */
apr_terminate();
return 0;
}
#endif /* APR_HAS_THREADS */
Je me demande toujours si c'est à ce genre de chose que Plauger faisait
allusion.