Por que 'main' não pode retornar um double ou String em vez de int ou nulo?

38

Em muitas linguagens como C, C ++ e Java, o mainmétodo / função tem um tipo de retorno de voidou int, mas não doubleou 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 maintem a assinatura de tipo que possui e não uma assinatura diferente?

JAVA
fonte
19
O que seria um valor de retorno dupla significa ? O que seria um valor de retorno corda significa ?
1
ki entendo que isso não significa nada.Mas outras razões e convenções?
JAVA
1
Eu acho que isso não significa nada, simplesmente porque, universalmente, foi escolhido que 0 para saída normal e um diferente de zero para um anormal.Um int foi escolhido como o tipo de dados mais simples, com ampla compatibilidade entre idiomas. @ delnan
JAVA
@sunny Pelo que pude reunir com a minha experiência com sistemas operacionais semelhantes ao Unix, 0 é usado como uma "saída normal" (0 erros) porque é inequívoco quando comparado a outros valores inteiros. Como a maioria das linguagens modernas (não todas) é projetada para ser semelhante a (se não projetada na parte de trás) do C, e como o C foi usado para escrever o Unix, eu diria que foi uma decisão histórica do KnR.
21813 Jamie Taylor
3
@sunny "ampla compatibilidade entre idiomas" não foi um problema. C e UNIX foram escritos em conjunto. A razão pela qual muitos outros idiomas retornam ints é porque eles foram projetados para funcionar em ambientes UNIX ou UNIX.

Respostas:

88

O valor de retorno de maindeve 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 ( 0x0001significa que isso falhou, 0x0002significa que falhou, 0x0003significa 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.

Sean Allred
fonte
2
Acho principal é chamado por c biblioteca / c ++ runtime antes OS chamá-lo de que é também um pedaço de código carregado junto com o nosso código e chamou pelo SO @ MichaelT
JAVA
5
main()é chamado de maneiras diferentes em diferentes sistemas operacionais. Em C, como é chamado inicialmente o método main ()? entra nisso.
25
Eu acho que o ponto principal a entender é que 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.
precisa
2
A IBM levou o conceito de páginas de código do EBCDIC para seus PCs. Eles ainda nos assombram hoje, continuando 35 anos após a introdução do IBM 5150. O ASCII de 7 bits não possui páginas de código, mas os códigos de caracteres de 8 bits podem ser interpretados de várias maneiras diferentes, mesmo em um único computador, dependendo das configurações - - e muito menos as páginas de código que codificam para codificações de vários bytes. Portanto, na verdade, é ainda pior do que você alude na última frase do segundo parágrafo.
um CVn 01/07/2013
@EuroMicelli isso é uma informação muito bom, na verdade obrigado por isso :)
JAVA
29

Bem, poderia .

Por exemplo, no dialeto C usado no sistema operacional Plan 9main é normalmente declarado como uma voidfunção, mas o status de saída é retornado ao ambiente de chamada passando um ponteiro de sequência para a exits()função. A sequência vazia indica sucesso e qualquer sequência não vazia indica algum tipo de falha. Isso poderia ter sido implementado mainretornando um char*resultado.

E certamente seria possível implementar um sistema com um status de saída floatou double.

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 ++ 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 .)intvoid mainvoid main

Keith Thompson
fonte
9

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).

xerânico
fonte
3
Por que uma string precisa ser coletada como lixo, enquanto um número inteiro não?
28413 Brad
4
@ Brad, as strings têm comprimento variável para elas e seriam essencialmente o mesmo que devolver uma matriz que poderia ter um caractere ou milhares. Memória dinâmica seria uma dor, enquanto int é um tamanho bastante fixo que não é tão difícil de lidar.
JB rei
-4

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.

dileepkumar p
fonte
1
isso parece não oferecer nada substancial sobre os pontos apresentados (e muito melhor explicados) em respostas anteriores publicadas há vários anos
gnat