Eu só estava lendo
ISO / IEC 9899: 201x Minuta do Comitê - 12 de abril de 2011
em que encontrei em 5.1.2.2.3 Término do programa
..reaching the } that terminates the main function returns a value of 0.
isso significa que se você não especificar nenhuma instrução return em main()
e se o programa for executado com êxito, a chave de fechamento} de main retornará 0.
Mas no código a seguir eu não especifico nenhuma instrução de retorno, ainda que não retorne 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);
}
compilar
gcc test.c
./a.out
sum is 15
echo $?
9 // here it should be 0 but it shows 9 why?
gcc
por si só (para a versão 4.6.2) compila uma linguagem muito semelhante, mas não exatamente como C. Ele compila o GnuC89 - uma linguagem "vagamente" baseada no C89.return
declaração emsum()
são desnecessários.int main()
deveria serint main(void)
.Respostas:
Essa regra foi adicionada na versão de 1999 do padrão C. No C90, o status retornado é indefinido.
Você pode habilitá-lo passando
-std=c99
para o gcc.Como uma nota lateral, curiosamente 9 é retornado porque é o retorno do
printf
qual apenas escreveu 9 caracteres.fonte
return 0;
antes do fechamento}
. É inofensivo e torna seu programa portátil para compiladores mais antigos.eax
especificamente no x86.eax
registro. Consulte en.wikipedia.org/wiki/X86_calling_conventions#cdecl para obter mais informações.Ele retorna o valor de retorno do
printf
qual é o número de caracteres realmente impressos.fonte
%errorlevel%
no Windows, há alguma diferença entre o código de saída e o valor de retorno domain
no linux?printf
que neste caso é 9, que então é "promovido" como o código de saída demain
alguma forma ao usar certas versões do gcc.O valor de retorno de uma função é normalmente armazenado no registrador eax da cpu, portanto, a instrução "return 4;" normalmente compilaria para
e o retorno x (dependendo do seu compilador) seria algo como:
se você não especificar um valor de retorno, o compilador ainda emitirá o "ret", mas não alterará o valor de eax. Portanto, o chamador pensará que o que foi deixado no registrador eax anteriormente é o valor de retorno. Para este exemplo, normalmente seria o valor de retorno printf, mas diferentes compiladores irão gerar diferentes códigos de máquina e usar alguns registradores de forma diferente.
Esta é uma explicação simplificada, diferentes convenções de chamada e plataformas de destino desempenharão um papel vital, mas deve ser informação suficiente para explicar o que está acontecendo 'nos bastidores' em seu exemplo.
Se você tem um conhecimento básico de assembler, vale a pena comparar a desmontagem de diferentes compiladores. Você pode descobrir que alguns compiladores estão limpando o registro eax como uma proteção.
fonte