Em muitas linguagens como C, C ++ e Java, o main
método / função tem um tipo de retorno de void
ou int
, mas não double
ou String
. Quais podem ser as razões por trás disso?
Eu sei um pouco que não podemos fazer isso porque main
é chamado por biblioteca de tempo de execução e que espera alguma sintaxe como int main()
ou int main(int,char**)
por isso temos de manter a mesma.
Portanto, minha pergunta é: por que main
tem a assinatura de tipo que possui e não uma assinatura diferente?
Respostas:
O valor de retorno de
main
deve ser passado para o sistema operacional ( qualquer sistema operacional) de uma maneira única e consistente. As informações que o sistema operacional precisa saber é "o programa foi encerrado com êxito ou ocorreu um erro?"Se for uma string, a resposta se torna difícil em diferentes idiomas. As partes internas de uma sequência de caracteres Pascal (o primeiro byte é comprimento) e uma sequência FORTRAN (fixa, preenchida com algum valor) e uma sequência C (terminação nula) são diferentes. Isso tornaria o retorno de um valor consistente para o sistema operacional um desafio. Supondo que isso foi resolvido, o que você faria para responder à pergunta que o sistema operacional tinha do programa? As comparações de cadeias estão repletas de erros ("sucesso" vs "Sucesso") e, embora o erro possa ser mais útil para um ser humano, é mais difícil para o sistema operacional ou outro programa (shell) lidar. Também houve diferenças significativas nas próprias strings - EBCDIC (com todas as suas páginas de código) vs. ASCII.
Flutuadores e duplos não fornecem valor adicional sobre o número inteiro para comunicar dados de volta ao SO (e shell). Na maioria das vezes, nenhuma dessas partes do computador lida com números de ponto flutuante. Dobros também não são numerosos, dificultando as comparações. Não sendo enumeráveis, eles relatam qual foi o erro (assumindo que você escolheu um valor específico para o sucesso). Novamente, os pontos flutuantes não são consistentes - um flutuador em uma máquina de 8 bits era diferente do flutuador em uma máquina de 16 e 32 bits (e esses são apenas os 'normais' - mesmo na IBM, o ponto flutuante não era padronizado entre máquinas do mesmo fabricante até os anos 80). E então você tem computadores decimais versus computadores binários. Os valores de ponto flutuante não são consistentes e não fornecem dados significativos de volta.
Isso realmente nos deixa com o byte e o inteiro como opções. A convenção estabelecida foi '0' foi bem-sucedida e qualquer outra coisa foi um erro. Um número inteiro oferece mais espaço que um byte para relatar o erro. Pode ser enumerado (retorno de 1 significa XYZ, retorno de 2 significa ABC, retorno de 3, significa DEF, etc.) ou usado como sinalizadores (
0x0001
significa que isso falhou,0x0002
significa que falhou,0x0003
significa isso e que falhou). Limitar isso a apenas um byte poderia facilmente ficar sem sinalizadores (apenas 8); portanto, a decisão provavelmente foi usar um número inteiro.fonte
main()
é chamado de maneiras diferentes em diferentes sistemas operacionais. Em C, como é chamado inicialmente o método main ()? entra nisso.main
- diferente de outras funções em qualquer programa - não faz parte de um protocolo definido pelo programador, mas o protocolo usado para fazer interface com o host (SO). Você não escolhe porque nunca foi sua. Em um nível mais pragmático, o UNIX espera que um int seja retornado por um processo e, portanto, o protocolo C-para-UNIX faz exatamente isso. Um argumento análogo pode ser feito para a passagem de argumentos: se C tivesse sido inventado para um SO / host que passasse apenas números como argumentos (por exemplo, nenhuma linha de comando), os argumentos seriam ints em vez de strings.Bem, poderia .
Por exemplo, no dialeto C usado no sistema operacional Plan 9
main
é normalmente declarado como umavoid
função, mas o status de saída é retornado ao ambiente de chamada passando um ponteiro de sequência para aexits()
função. A sequência vazia indica sucesso e qualquer sequência não vazia indica algum tipo de falha. Isso poderia ter sido implementadomain
retornando umchar*
resultado.E certamente seria possível implementar um sistema com um status de saída
float
oudouble
.Então porque
int
? É apenas uma questão de convenção - e há um valor tremendo em ter sistemas operacionais e programas executados sob elas obedecer a uma convenção comum.A convenção do Unix é usar um código de status inteiro, com 0 indicando sucesso e falha diferente de zero (porque normalmente há apenas uma maneira de obter sucesso, mas várias maneiras de falhar). Não sei se essa convenção se originou no Unix; Eu suspeito que veio de sistemas operacionais anteriores.
Ponto flutuante seria uma convenção mais difícil, porque (a) o suporte a ponto flutuante não é universal, (b) é mais difícil definir um mapeamento entre valores de ponto flutuante e condições de erro, (c) sistemas diferentes usam diferentes flutuantes. representações de pontos e (d) imagine a diversão de rastrear um erro de arredondamento no status de saída do seu programa. Os números inteiros, por outro lado, se prestam muito bem à enumeração de códigos de erro.
O Plano 9, como mencionei, usa cadeias de caracteres, mas isso impõe alguma complexidade para gerenciamento de memória, codificação de caracteres etc. Era, até onde eu sei, uma nova idéia quando o Plano 9 o implementou e não substituiu os existentes. convenção generalizada.
(Aliás, em C ++ só
main
pode retornar , e em C é permitido apenas se o compilador o suportar especificamente. Muitos compiladores não reclamam muito alto se você escreve , mas é apenas um pequeno exagero dizer que está errado .)int
void main
void main
fonte
O valor retornado pelo método principal é um "código de saída". É usado pelo aplicativo de chamada (normalmente bash) para testar se o programa foi finalizado conforme o esperado. Retornar um número inteiro é a maneira mais fácil de fazer isso no nível do SO. Double não faz sentido para o código de erro e é difícil manter uma String no nível do SO (não há GC).
fonte
main deve retornar o status do programa que é executado. se ele é executado com êxito (retorno 0 que é EXIT_SUCCESS) ou não (retorno 1 significa EXIT_FAILURE) qualquer número diferente de zero transmite o mesmo significado, mas zero indica que não há erros ou execução bem-sucedida.
fonte