O que deve main () retornar em C e C ++?

Qual é a maneira correta (mais eficiente) de definir a function main() em C e C ++ – int main() ou void main() – e por quê? Se int main() então return 1 ou return 0 ?


Existem numerosas duplicatas desta questão, incluindo:

  • Quais são as assinaturas válidas para a function main() do C?
  • O tipo de retorno da function main()
  • Diferença entre void main() e int main() ?
  • assinatura do main() em C ++
  • Qual é a declaração correta de main() ? – Para C ++, com uma resposta muito boa, de fato.
  • Estilos de funções main() em C
  • Retorna o tipo do método main() em C
  • int main() vs void main() em C

Relacionado:

  • C ++ – int main(int argc, char **argv)
  • C ++ – int main(int argc, char *argv[])
  • É char *envp[] como um terceiro argumento para main() portable?
  • A function int main() retornar um valor em todos os compiladores?
  • Por que o tipo da function main() em C e C ++ é deixado para o usuário definir?
  • Por que int main(){} compila?
  • Definições legais de main() em C ++ 14?

    O valor de retorno para main deve indicar como o programa foi encerrado. A saída normal é geralmente representada por um valor de retorno 0 do main . A terminação anormal é geralmente sinalizada por um retorno diferente de zero, mas não há um padrão para como os códigos diferentes de zero são interpretados. Também como observado por outros, void main() é explicitamente proibido pelo padrão C ++ e não deve ser usado. As assinaturas main C ++ válidas são:

     int main() 

    e

     int main(int argc, char* argv[]) 

    que é equivalente a

     int main(int argc, char** argv) 

    Também é importante notar que em C ++, int main() pode ser deixado sem um valor de retorno no ponto em que o padrão é retornar 0. Isso também é verdade com um programa C99. Se o retorno 0 deve ser omitido ou não está aberto para debate. O intervalo de assinaturas principais do programa C válido é muito maior.

    Além disso, a eficiência não é um problema com a function main . Só pode ser inserido e deixado uma vez (marcação de início e término do programa) de acordo com o padrão C ++. Para C, o caso é diferente e reentrar main() é permitido, mas provavelmente deve ser evitado.

    A resposta aceita parece ser direcionada para C ++, então eu pensei em adicionar uma resposta que pertence a C, e isso difere de algumas maneiras.

    ISO / IEC 9899: 1989 (C90):

    main() deve ser declarado como:

     int main(void) int main(int argc, char **argv) 

    Ou equivalente. Por exemplo, int main(int argc, char *argv[]) é equivalente ao segundo. Além disso, o tipo de retorno int pode ser omitido, pois é um padrão.

    Se uma implementação permitir, main() pode ser declarado de outras formas, mas isso torna a implementação do programa definida e não mais estritamente conforme.

    O padrão define 3 valores para retornar que estão estritamente em conformidade (isto é, não depende do comportamento definido pela implementação): 0 e EXIT_SUCCESS para uma finalização bem-sucedida e EXIT_FAILURE para uma finalização malsucedida. Quaisquer outros valores não são padrão e a implementação é definida. main() deve ter uma declaração de return explícita no final para evitar um comportamento indefinido.

    Finalmente, não há nada de errado do ponto de vista dos padrões com a chamada main() de um programa.

    ISO / IEC 9899: 1999 (C99):

    Para C99, tudo é igual ao anterior, exceto:

    • O tipo de retorno int não pode ser omitido.
    • Você pode omitir a declaração de retorno de main() . Se você fizer isso e main() terminar, haverá um return 0 implícito return 0 .

    Padrão C – Ambiente Hospedado

    Para um ambiente hospedado (esse é o normal), o padrão C11 (ISO / IEC 9899: 2011) diz:

    5.1.2.2.1 Inicialização do programa

    A function chamada na boot do programa é chamada main . A implementação declara nenhum protótipo para esta function. Deve ser definido com um tipo de retorno de int e sem parâmetros:

     int main(void) { /* ... */ } 

    ou com dois parâmetros (referidos aqui como argc e argv , embora quaisquer nomes possam ser usados, pois são locais para a function em que são declarados):

     int main(int argc, char *argv[]) { /* ... */ } 

    ou equivalente; 10) ou de alguma outra forma definida pela implementação.

    Se forem declarados, os parâmetros para a function principal devem obedecer às seguintes restrições:

    • O valor de argc deve ser não-negativo.
    • argv[argc] deve ser um ponteiro nulo.
    • Se o valor de argc for maior que zero, os membros da matriz argv[0] por meio de argv[argc-1] inclusive deverão conter pointers para cadeias de caracteres, que recebem valores definidos pela implementação pelo ambiente do host antes da boot do programa. A intenção é fornecer as informações do programa determinadas antes da boot do programa em outro lugar no ambiente hospedado. Se o ambiente host não for capaz de fornecer strings com letras em maiúsculas e minúsculas, a implementação deve garantir que as strings sejam recebidas em letras minúsculas.
    • Se o valor de argc for maior que zero, a string apontada por argv[0] representa o nome do programa; argv[0][0] será o caractere nulo se o nome do programa não estiver disponível no ambiente do host. Se o valor de argc for maior que um, as strings apontadas por argv[1] por meio de argv[argc-1] representam os parâmetros do programa.
    • Os parâmetros argc e argv e as strings apontadas pela matriz argv devem ser modificáveis ​​pelo programa e reter seus últimos valores armazenados entre a boot do programa e a finalização do programa.

    10) Assim, int pode ser substituído por um nome typedef definido como int , ou o tipo de argv pode ser escrito como char **argv e assim por diante.

    Terminação do programa em C99 ou C11

    O valor retornado de main() é transmitido para o ‘ambiente’ de uma maneira definida pela implementação.

    5.1.2.2.3 Terminação do programa

    1 Se o tipo de retorno da function main é um tipo compatível com int , um retorno da chamada inicial para a function main é equivalente a chamar a function exit com o valor retornado pela function main como seu argumento; 11) alcançar o } que termina a function main retorna um valor de 0. Se o tipo de retorno não for compatível com int , o status de finalização retornado para o ambiente host não será especificado.

    11) De acordo com 6.2.4, o tempo de vida de objects com duração de armazenamento automático declarada em main terá terminado no primeiro caso, mesmo onde eles não teriam no último caso.

    Note que 0 é obrigatório como ‘sucesso’. Você pode usar EXIT_FAILURE e EXIT_SUCCESS de se preferir, mas 0 está bem estabelecido e, portanto, é 1. Consulte também Códigos de saída maiores que 255 – possíveis? .

    Em C89 (e, portanto, no Microsoft C), não há nenhuma declaração sobre o que acontece se a function main() retorna, mas não especifica um valor de retorno; portanto, leva a um comportamento indefinido.

    7.22.4.4 A function de exit

    ¶5 Finalmente, o controle é retornado para o ambiente host. Se o valor do status for zero ou EXIT_SUCCESS , será EXIT_SUCCESS uma forma definida pela implementação da terminação com sucesso do status. Se o valor do status for EXIT_FAILURE , será EXIT_FAILURE um formulário definido pela implementação da terminação sem êxito do status. Caso contrário, o status retornado será definido pela implementação.

    Padrão C ++ – Ambiente Hospedado

    O padrão C ++ 11 (ISO / IEC 14882: 2011) diz:

    3.6.1 Função principal [basic.start.main]

    ¶1 Um programa deve conter uma function global chamada main, que é o início designado do programa. […]

    ¶2 Uma implementação não deve pré-definir a function principal. Esta function não deve ser sobrecarregada. Ele deve ter um tipo de retorno do tipo int, mas, caso contrário, seu tipo é definido pela implementação. Todas as implementações devem permitir ambas as seguintes definições de main:

     int main() { /* ... */ } 

    e

     int main(int argc, char* argv[]) { /* ... */ } 

    Na última forma argc deve ser o número de argumentos passados ​​para o programa a partir do ambiente em que o programa é executado. Se argc for diferente de zero, esses argumentos devem ser fornecidos em argv[0] a argv[argc-1] pois os pointers para os caracteres iniciais de strings multibyte terminados em nulo (NTMBSs) (17.5.2.1.4.2) e argv[0] devem ser o ponteiro para o caractere inicial de um NTMBS que representa o nome usado para chamar o programa ou "" . O valor de argc deve ser não negativo. O valor de argv[argc] deve ser 0. [Nota: Recomenda-se que quaisquer outros parâmetros (opcionais) sejam adicionados após o argv . – end note]

    ¶3 A function main não deve ser usada dentro de um programa. A binding (3.5) do main é definida pela implementação. […]

    ¶5 Uma instrução de retorno em main tem o efeito de deixar a function principal (destruindo quaisquer objects com duração de armazenamento automático) e chamando std::exit com o valor de retorno como o argumento. Se o controle atingir o final do main sem encontrar uma declaração de retorno, o efeito é o de executar

     return 0; 

    O padrão C ++ explicitamente diz “Ele [a function principal] deve ter um tipo de retorno do tipo int , mas seu tipo é implementado definido”, e requer as mesmas duas assinaturas que o padrão C para ser suportado como opções. Portanto, um ‘void main ()’ não é diretamente permitido pelo padrão C ++, embora não haja nada que possa ser feito para impedir que uma implementação não padrão permita alternativas. Observe que o C ++ proíbe o usuário de chamar main (mas o padrão C não).

    Há um parágrafo de §18.5 Início e término no padrão C ++ 11 que é idêntico ao parágrafo de §7.22.4.4 A function de exit no padrão C11 (citada acima), além de uma nota de rodapé (que simplesmente documenta que EXIT_SUCCESS e EXIT_FAILURE são definidos em ).

    Padrão C – Extensão Comum

    Classicamente, os sistemas Unix suportam uma terceira variante:

     int main(int argc, char **argv, char **envp) { ... } 

    O terceiro argumento é uma lista terminada em nulo de pointers para strings, cada um dos quais é uma variável de ambiente que tem um nome, um sinal de igual e um valor (possivelmente vazio). Se você não usar isso, você ainda pode obter no ambiente via ‘ extern char **environ; ‘. Por muito tempo, isso não teve um header que o declarou, mas o padrão POSIX 2008 agora exige que ele seja declarado em .

    Isto é reconhecido pela norma C como uma extensão comum, documentada no Anexo J:

    J.5.1 Argumentos do ambiente

    ¶1 Em um ambiente hospedado, a function principal recebe um terceiro argumento, char *envp[] , que aponta para uma matriz de pointers terminada em nulo para char , cada um dos quais aponta para uma cadeia que fornece informações sobre o ambiente para essa execução. do programa (5.1.2.2.1).

    Microsoft C

    O compilador do Microsoft VS 2010 é interessante. O site diz:

    A syntax da declaração para main é

      int main(); 

    ou, opcionalmente,

     int main(int argc, char *argv[], char *envp[]); 

    Alternativamente, as funções main e wmain podem ser declaradas como retornando void (sem valor de retorno). Se você declarar main ou wmain como retornar void, não será possível retornar um código de saída para o processo pai ou sistema operacional usando uma instrução de retorno. Para retornar um código de saída quando main ou wmain for declarado como void , você deve usar a function exit .

    Não está claro para mim o que acontece (qual código de saída é retornado para o pai ou sistema operacional) quando um programa com void main() é encerrado – e o site da MS fica em silêncio também.

    Curiosamente, o MS não prescreve a versão de dois argumentos do main() que os padrões C e C ++ requerem. Ele apenas prescreve um formulário de três argumentos em que o terceiro argumento é char **envp , um ponteiro para uma lista de variables ​​de ambiente.

    A página da Microsoft também lista algumas outras alternativas – wmain() que usa seqüências de caracteres largas e outras mais.

    A versão do Microsoft Visual Studio 2005 desta página não lista void main() como uma alternativa. As versões do Microsoft Visual Studio 2008 em diante fazem.

    Padrão C – Ambiente Independente

    Conforme observado anteriormente, os requisitos acima se aplicam a ambientes hospedados. Se você estiver trabalhando com um ambiente independente (que é a alternativa para um ambiente hospedado), o padrão terá muito menos a dizer. Para um ambiente independente, a function chamada na boot do programa não precisa ser chamada de main e não há restrições em seu tipo de retorno. O padrão diz:

    5.1.2 Ambientes de execução

    Dois ambientes de execução são definidos: independentes e hospedados. Em ambos os casos, a boot do programa ocorre quando uma function C designada é chamada pelo ambiente de execução. Todos os objects com duração de armazenamento estático devem ser inicializados (definidos para seus valores iniciais) antes da boot do programa. A maneira e o tempo de tal boot não são especificados. A finalização do programa retorna o controle para o ambiente de execução.

    5.1.2.1 Ambiente autônomo

    Em um ambiente independente (no qual a execução do programa C pode ocorrer sem qualquer benefício de um sistema operacional), o nome e o tipo da function chamada na boot do programa são definidos pela implementação. Qualquer biblioteca disponível para um programa independente, diferente do conjunto mínimo exigido pela cláusula 4, é definida pela implementação.

    O efeito da finalização do programa em um ambiente independente é definido pela implementação.

    A referência cruzada à cláusula 4 Conformidade refere-se a isto:

    ¶ 5 Um programa estritamente em conformidade usará apenas os resources do idioma e da biblioteca especificados nesta Norma. 3) Não deve produzir saída dependente de qualquer comportamento não especificado, indefinido ou definido pela implementação, e não deve exceder qualquer limite mínimo de implementação.

    ¶6 As duas formas de implementação em conformidade são hospedadas e independentes . Uma implementação hospedada conforme deve aceitar qualquer programa estritamente conforme. Uma implementação autônoma em conformidade deve aceitar qualquer programa estritamente conforme em que o uso dos resources especificados na cláusula da biblioteca (cláusula 7) esteja restrito ao conteúdo dos headers padrão , , , , , , , e . Uma implementação em conformidade pode ter extensões (incluindo funções adicionais da biblioteca), desde que elas não alterem o comportamento de qualquer programa estritamente conforme. 4)

    ¶7 Um programa em conformidade é aquele que é aceitável para uma implementação conforme. 5)

    3) Um programa estritamente em conformidade pode usar resources condicionais (ver 6.10.8.3) desde que o uso seja protegido por uma diretiva apropriada de pré-processamento de inclusão condicional usando a macro relacionada. Por exemplo:

     #ifdef __STDC_IEC_559__ /* FE_UPWARD defined */ /* ... */ fesetround(FE_UPWARD); /* ... */ #endif 

    4) Isso implica que uma implementação conforme não reserva nenhum identificador além daqueles explicitamente reservados nesta Norma.

    5) Programas estritamente conformes são planejados para serem portáteis máximos entre implementações em conformidade. Os programas em conformidade podem depender de resources não portáteis de uma implementação em conformidade.

    É perceptível que o único header necessário de um ambiente independente que realmente define qualquer function é (e mesmo esses podem ser – e geralmente são – apenas macros).

    Padrão C ++ – Ambiente Independente

    Assim como o padrão C reconhece ambientes hospedados e independentes, o mesmo ocorre com o padrão C ++. (Citações da ISO / IEC 14882: 2011)

    1.4 Conformidade com a implementação [intro.compliance]

    ¶7 Dois tipos de implementações são definidos: uma implementação hospedada e uma implementação independente . Para uma implementação hospedada, esta Norma define o conjunto de bibliotecas disponíveis. Uma implementação independente é aquela em que a execução pode ocorrer sem o benefício de um sistema operacional e possui um conjunto de bibliotecas definido pela implementação que inclui determinadas bibliotecas de suporte a idiomas (17.6.1.3).

    ¶8 Uma implementação em conformidade pode ter extensões (incluindo funções adicionais da biblioteca), desde que elas não alterem o comportamento de nenhum programa bem formado. Implementações são necessárias para diagnosticar programas que usam extensões que são mal formadas de acordo com esta Norma. Tendo feito isso, no entanto, eles podem compilar e executar tais programas.

    ¶9 Cada implementação deve include documentação que identifique todas as construções suportadas condicionalmente que não suportam e define todas as características específicas de localidade. 3

    3) Esta documentação também define o comportamento definido pela implementação; ver 1.9.

    17.6.1.3 Implementações independentes [conformidade]

    Dois tipos de implementações são definidos: hospedados e independentes (1.4). Para uma implementação hospedada, esta Norma descreve o conjunto de headers disponíveis.

    Uma implementação independente tem um conjunto de headers definidos pela implementação. Este conjunto deve include pelo menos os headers mostrados na Tabela 16.

    A versão fornecida do header deve declarar pelo menos as funções abort , atexit , at_quick_exit , exit e quick_exit (18.5). Os outros headers listados nesta tabela devem atender aos mesmos requisitos de uma implementação hospedada.

    Tabela 16 – Cabeçalhos C ++ para Implementações Independentes

     Subclause Header(s)  18.2 Types  18.3 Implementation properties    18.4 Integer types  18.5 Start and termination  18.6 Dynamic memory management  18.7 Type identification  18.8 Exception handling  18.9 Initializer lists  18.10 Other runtime support    20.9 Type traits  29 Atomics  

    Que tal usar int main() em C?

    O padrão §5.1.2.2.1 do padrão C11 mostra a notação preferida – int main(void) – mas há também dois exemplos no padrão que mostram int main() : §6.5.3.4 ¶8 e §6.7.6.3 ¶20 . Agora, é importante notar que os exemplos não são “normativos”; eles são apenas ilustrativos. Se houver erros nos exemplos, eles não afetarão diretamente o texto principal do padrão. Dito isso, eles são fortemente indicativos do comportamento esperado, portanto, se o padrão include int main() em um exemplo, ele sugere que int main() não é proibido, mesmo que não seja a notação preferida.

    6.5.3.4 Operadores sizeof e _Alignof

    ¶8 EXEMPLO 3 Neste exemplo, o tamanho de uma matriz de comprimento variável é calculado e retornado de uma function:

     #include  size_t fsize3(int n) { char b[n+3]; // variable length array return sizeof b; // execution time sizeof } int main() { size_t size; size = fsize3(10); // fsize3 returns 13 return 0; } 

    Eu acredito que main() deve retornar EXIT_SUCCESS ou EXIT_FAILURE . Eles estão definidos em stdlib.h

    Retornar 0 no sucesso e diferente de zero para erro. Este é o padrão usado pelos scripts UNIX e DOS para descobrir o que aconteceu com o seu programa.

    Observe que os padrões C e C ++ definem dois tipos de implementação: independentes e hospedados.

    • Ambiente hospedado C90

      Formulários permitidos 1 :

       int main (void) int main (int argc, char *argv[]) main (void) main (int argc, char *argv[]) /*... etc, similar forms with implicit int */ 

      Comentários:

      Os dois primeiros são explicitamente declarados como os formulários permitidos, os outros são implicitamente permitidos porque o C90 permitia “int implícito” para parâmetros de tipo e function de retorno. Nenhuma outra forma é permitida.

    • Ambiente autônomo C90

      Qualquer forma ou nome de main é permitido 2 .

    • Ambiente hospedado C99

      Formas permitidas 3 :

       int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */ 

      Comentários:

      C99 removido “int implícito” assim main() não é mais válido.

      Uma frase estranha e ambígua “ou de alguma outra forma definida pela implementação” foi introduzida. Isso pode ser interpretado como “os parâmetros para int main() podem variar” ou como “main pode ter qualquer formulário definido pela implementação”.

      Alguns compiladores optaram por interpretar o padrão do último modo. Indiscutivelmente, não se pode afirmar facilmente que eles não estão estritamente conformes, citando o padrão em si, já que é ambíguo.

      No entanto, para permitir formas completamente selvagens de main() foi provavelmente (?) Não a intenção desta nova sentença. A lógica C99 (não normativa) implica que a sentença se refere a parâmetros adicionais para int main 4 .

      No entanto, a seção para encerramento do programa de ambiente hospedado, em seguida, continua discutindo sobre o caso em que main não retorna int 5 . Embora essa seção não seja normativa sobre como o main deve ser declarado, isso definitivamente implica que main pode ser declarado de uma forma completamente definida pela implementação, mesmo em sistemas hospedados.

    • Ambiente autônomo C99

      Qualquer forma ou nome de main é permitido 6 .

    • Ambiente hospedado C11

      Formas permitidas 7 :

       int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */ 
    • Ambiente autônomo C11

      Qualquer forma ou nome de main é permitido 8 .


    Note que int main() nunca foi listado como um formulário válido para qualquer implementação hospedada de C em qualquer uma das versões acima. Em C, ao contrário de C ++, () e (void) têm significados diferentes. O primeiro é um recurso obsoleto que pode ser removido da linguagem. Veja C11 futuras direções de linguagem:

    6.11.6 Declaradores de Função

    O uso de declaradores de function com parênteses vazios (não declaradores de tipo de parâmetro no formato de protótipo) é um recurso obsoleto.


    • Ambiente hospedado C ++ 03

      Formulários permitidos 9 :

       int main () int main (int argc, char *argv[]) 

      Comentários:

      Observe o parêntese vazio no primeiro formulário. C ++ e C são diferentes nesse caso, porque em C ++ isso significa que a function não usa parâmetros. Mas em C isso significa que pode pegar qualquer parâmetro.

    • C ++ 03 ambiente autônomo

      O nome da function chamada na boot é definido pela implementação. Se é chamado main() , deve seguir os formulários indicados 10 :

       // implementation-defined name, or int main () int main (int argc, char *argv[]) 
    • Ambiente hospedado C ++ 11

      Formulários permitidos 11 :

       int main () int main (int argc, char *argv[]) 

      Comentários:

      O texto do padrão foi alterado, mas tem o mesmo significado.

    • Ambiente autônomo C ++ 11

      O nome da function chamada na boot é definido pela implementação. Se é chamado main() , deve seguir os formulários indicados 12 :

       // implementation-defined name, or int main () int main (int argc, char *argv[]) 

    Referências

    1. ANSI X3.159-1989 2.1.2.2 Ambiente hospedado. “Inicialização do programa”

      A function chamada na boot do programa é chamada principal. A implementação declara nenhum protótipo para esta function. Deve ser definido com um tipo de retorno de int e sem parâmetros:

       int main(void) { /* ... */ } 

      ou com dois parâmetros (referidos aqui como argc e argv, embora quaisquer nomes possam ser usados, pois são locais para a function em que são declarados):

       int main(int argc, char *argv[]) { /* ... */ } 
    2. ANSI X3.159-1989 2.1.2.1 Ambiente independente:

      Em um ambiente independente (no qual a execução do programa C pode ocorrer sem qualquer benefício de um sistema operacional), o nome e o tipo da function chamada na boot do programa são definidos pela implementação.

    3. ISO 9899: 1999 5.1.2.2 Ambiente hospedado -> 5.1.2.2.1 Inicialização do programa

      A function chamada na boot do programa é chamada principal. A implementação declara nenhum protótipo para esta function. Deve ser definido com um tipo de retorno de int e sem parâmetros:

       int main(void) { /* ... */ } 

      ou com dois parâmetros (referidos aqui como argc e argv, embora quaisquer nomes possam ser usados, pois são locais para a function em que são declarados):

       int main(int argc, char *argv[]) { /* ... */ } 

      ou equivalente, 9) ou de alguma outra forma definida pela implementação.

    4. Justificativa para o Padrão Internacional – Linguagens de Programação – C, Revisão 5.10. 5.1.2.2 Ambiente hospedado -> 5.1.2.2.1 Inicialização do programa

      The behavior of the arguments to main, and of the interaction of exit, main and atexit (see §7.20.4.2) has been codified to curb some unwanted variety in the representation of argv strings, and in the meaning of values returned by main.

      The specification of argc and argv as arguments to main recognizes extensive prior practice. argv[argc] is required to be a null pointer to provide a redundant check for the end of the list, also on the basis of common practice.

      main is the only function that may portably be declared either with zero or two arguments. (The number of other functions’ arguments must match exactly between invocation and definition.) This special case simply recognizes the widespread practice of leaving off the arguments to main when the program does not access the program argument strings. While many implementations support more than two arguments to main, such practice is neither blessed nor forbidden by the Standard; a program that defines main with three arguments is not strictly conforming (see §J.5.1.).

    5. ISO 9899:1999 5.1.2.2 Hosted environment –> 5.1.2.2.3 Program termination

      If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

    6. ISO 9899:1999 5.1.2.1 Freestanding environment

      In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined.

    7. ISO 9899:2011 5.1.2.2 Hosted environment -> 5.1.2.2.1 Program startup

      This section is identical to the C99 one cited above.

    8. ISO 9899:1999 5.1.2.1 Freestanding environment

      This section is identical to the C99 one cited above.

    9. ISO 14882:2003 3.6.1 Main function

      An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:

       int main() { /* ... */ } 

      e

       int main(int argc, char* argv[]) { /* ... */ } 
    10. ISO 14882:2003 3.6.1 Main function

      It is implementation-defined whether a program in a freestanding environment is required to define a main function.

    11. ISO 14882:2011 3.6.1 Main function

      An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both

      — a function of () returning int and

      — a function of (int, pointer to pointer to char) returning int

      as the type of main (8.3.5).

    12. ISO 14882:2011 3.6.1 Main function

      This section is identical to the C++03 one cited above.

    Keep in mind that,even though you’re returning an int, some OSes (Windows) truncate the returned value to a single byte (0-255).

    main() in C89 and K&R C unspecified return types default to ‘int`.

     return 1? return 0? 
    1. If you do not write a return statement in int main() , the closing { will return 0 by default.

    2. return 0 or return 1 will be received by the parent process. In a shell it goes into a shell variable, and if you are running your program form a shell and not using that variable then you need not worry about the return value of main() .

    See How can I get what my main function has returned? .

     $ ./a.out $ echo $? 

    This way you can see that it is the variable $? which receives the least significant byte of the return value of main() .

    In Unix and DOS scripting, return 0 on success and non-zero for error are usually returned. This is the standard used by Unix and DOS scripting to find out what happened with your program and controlling the whole flow.

    The return value can be used by the operating system to check how the program was closed.

    Return value 0 usually means OK in most operating systems (the ones I can think of anyway).

    It also can be checked when you call a process yourself, and see if the program exited and finished properly.

    It’s NOT just a programming convention.

    I was under the impression that standard specifies that main doesn’t need a return value as a successful return was OS based (zero in one could be either a success or a failure in another), therefore the absence of return was a cue for the compiler to insert the successful return itself.

    However I usually return 0.

    The return value of main() shows how the program exited. If the return value is zero it means that the execution was successful while any non-zero value will represent that something went bad in the execution.

    Returning 0 should tell the programmer that the program has successfully finished the job.

    What to return depends on what you want to do with the executable. For example if you are using your program with a command line shell, then you need to return 0 for a success and a non zero for failure. Then you would be able to use the program in shells with conditional processing depending on the outcome of your code. Also you can assign any nonzero value as per your interpretation, for example for critical errors different program exit points could terminate a program with different exit values , and which is available to the calling shell which can decide what to do by inspecting the value returned. If the code is not intended for use with shells and the returned value does not bother anybody then it might be omitted. I personally use the signature int main (void) { .. return 0; .. }

    If you really have issues related to efficiency of returning an integer from a process, you should probably avoid to call that process so many times that this return value becomes an issue.

    If you are doing this (call a process so many times), you should find a way to put your logic directly inside the caller, or in a DLL file, without allocate a specific process for each call; the multiple process allocations bring you the relevant efficiency problem in this case.

    In detail, if you only want to know if returning 0 is more or less efficient than returning 1, it could depend from the compiler in some cases, but generically, assuming they are read from the same source (local, field, constant, embedded in the code, function result, etc.) it requires exactly the same number of clock cycles.

    In C++ the main function should be declared as int main() and not void main() as the compiler then throws an error in the case of void main. The main function can take any number of arguments like int main(int k,int l,int arr[]) or int main(void).

     #include  using namespace std; int main(void) { // your code goes here cout< <"a"; return 0; } 

    Saída:

     Success #stdin #stdout 0s 4416KB a 

    Coming to the return part it should return only 0 else the compiler throws an error. for example if you return 1,you will get the desired output but it also throws a runtime error.

    Exemplo

     #include  using namespace std; int main(int k,float m,char g, int arr[]) { // your code goes here k=0; cout<  

    Saída:

     Runtime error #stdin #stdout 0s 4448KB 0aa 

    Here is a small demonstration of the usage of return codes…

    When using the various tools that the Linux terminal provides one can use the return code for example for error handling after the process has been completed. Imagine that the following text file myfile is present:

    This is some example in order to check how grep works.

    When you execute the grep command a process is created. Once it is through (and didn’t break) it returns some code between 0 and 255. For example:

     $ grep order myfile 

    Se você fizer

     $ echo $? $ 0 

    you will get a 0. Why? Because grep found a match and returned an exit code 0, which is the usual value for exiting with a success. Let’s check it out again but with something that is not inside our text file and thus no match will be found:

     $ grep foo myfile $ echo $? $ 1 

    Since grep failed to match the token “foo” with the content of our file the return code is 1 (this is the usual case when a failure occurs but as stated above you have plenty of values to choose from).

    Now the following bash script (simply type it in a Linux terminal) although very basic should give some idea of error handling:

     $ grep foo myfile $ CHECK=$? $ [ $CHECK -eq 0] && echo 'Match found' $ [ $CHECK -ne 0] && echo 'No match was found' $ No match was found 

    After the second line nothing is printed to the terminal since “foo” made grep return 1 and we check if the return code of grep was equal to 0. The second conditional statement echoes its message in the last line since it is true due to CHECK == 1.

    As you can see if you are calling this and that process it is sometimes essential to see what it has returned (by the return value of main()).

    Omit return 0

    When a C or C++ program reaches the end of main the compiler will automatically generate code to return 0, so there is no need to put return 0; explicitly at the end of main .

    Note: when I make this suggestion, it’s almost invariably followed by one of two kinds of comments: “I didn’t know that.” or “That’s bad advice!” My rationale is that it’s safe and useful to rely on compiler behavior explicitly supported by the standard. For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:

    […] a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.

    For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:

    If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

    All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to “it looks weird” . If, like me, you’re curious about the rationale for the change to the C standard read this question . Also note that in the early 1990s this was considered “sloppy practice” because it was undefined behavior (although widely supported) at the time.

    So I advocate omitting it; others disagree (often vehemently!) In any case, if you encounter code that omits it, you’ll know that it’s explicitly supported by the standard and you’ll know what it means.

    What is the correct (most efficient) way to define the main() function in C and C++ — int main() or void main() — and why?

    Those words “(most efficient)” don’t change the question. Unless you’re in a freestanding environment, there is one universally correct way to declare main() , and that’s as returning int.

    What should main() return in C and C++?

    It’s not what should main() return, it’s what does main() return. main() is, of course, a function that someone else calls. You don’t have any control over the code that calls main() . Therefore, you must declare main() with a type-correct signature to match its caller. You simply don’t have any choice in the matter. You don’t have to ask yourself what’s more or less efficient, or what’s better or worse style, or anything like that, because the answer is already perfectly well defined, for you, by the C and C+ standards. Just follow them.

    If int main() then return 1 or return 0?

    0 for success, nonzero for failure. Again, not something you need to (or get to) pick: it’s defined by the interface you’re supposed to be conforming to.

    This basically depends on your execution environment (the OS). C implies that it will be run by a UNIX like OS which expects the program to return a (small? 1 Byte? can’t remember) integer to indicate success / failure.

    You should probably just use int main(int argc, char** argv) .