Je lisais juste
Projet de comité ISO / CEI 9899: 201x - 12 avril 2011
dans lequel j'ai trouvé sous 5.1.2.2.3 Résiliation du programme
..reaching the } that terminates the main function returns a value of 0.
cela signifie que si vous ne spécifiez aucune instruction return dans main()
, et si le programme s'exécute avec succès, alors à l'accolade fermante} de main renverra 0.
Mais dans le code suivant, je ne spécifie aucune déclaration de retour, mais il ne renvoie pas 0
#include<stdio.h>
int sum(int a,int b)
{
return (a + b);
}
int main()
{
int a=10;
int b=5;
int ans;
ans=sum(a,b);
printf("sum is %d",ans);
}
compiler
gcc test.c
./a.out
sum is 15
echo $?
9 // here it should be 0 but it shows 9 why?
gcc
par lui-même (pour la version 4.6.2) compile un langage très similaire mais pas tout à fait semblable à C. Il compile GnuC89 - un langage "vaguement" basé sur C89.return
instruction danssum()
sont inutiles.int main()
devrait êtreint main(void)
.Réponses:
Cette règle a été ajoutée dans la version 1999 de la norme C. Dans C90, l'état renvoyé n'est pas défini.
Vous pouvez l'activer en passant
-std=c99
à gcc.En passant, il est intéressant de noter que 9 est renvoyé car c'est le retour
printf
dont vient d'écrire 9 caractères.la source
return 0;
avant la fermeture}
. C'est inoffensif et rend votre programme portable vers les anciens compilateurs.eax
spécifiquement sur x86.eax
registre. Voir en.wikipedia.org/wiki/X86_calling_conventions#cdecl pour plus d'informations.Il renvoie la valeur de retour
printf
dont le nombre de caractères réellement imprimés.la source
%errorlevel%
dans Windows, une différence entre le code de sortie et la valeur de retour demain
dans Linux?printf
qui dans ce cas est 9 qui est alors "promu" comme code de sortie d'unemain
manière ou d'une autre lors de l'utilisation de certaines versions de gcc.La valeur de retour d'une fonction est normalement stockée dans le registre eax du processeur, donc l'instruction "return 4;" compilerait généralement en
et return x (selon votre compilateur) serait quelque chose comme:
si vous ne spécifiez pas de valeur de retour, le compilateur crachera toujours le "ret" mais ne changera pas la valeur de eax. Ainsi, l'appelant pensera que ce qui a déjà été laissé dans le registre eax est la valeur de retour. Pour cet exemple, ce serait généralement la valeur de retour printf, mais différents compilateurs généreront un code machine différent et utiliseront certains registres différemment.
Il s'agit d'une explication simplifiée, différentes conventions d'appel et plates-formes cibles joueront un rôle essentiel, mais elles devraient être suffisamment d'informations pour expliquer ce qui se passe «en coulisse» dans votre exemple.
Si vous avez une compréhension de base de l'assembleur, il vaut la peine de comparer le désassemblage de différents compilateurs. Vous constaterez peut-être que certains compilateurs effacent le registre eax à titre de sauvegarde.
la source