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 função chamada na inicialização do programa é nomeada main
. A implementação declara nenhum protótipo para esta função. 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 qualquer nome possa ser usado, pois são locais para a função na qual são declarados):
int main(int argc, char *argv[]) { /* ... */ }
ou equivalente; 10) ou de alguma outra maneira definida pela implementação.
Se forem declarados, os parâmetros para a função 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]
inclusões deverão conter ponteiros para seqüências de caracteres, que recebem valores definidos pela implementação pelo ambiente host antes da inicialização do programa. A intenção é fornecer as informações do programa determinadas antes da inicialização do programa de outro local do ambiente hospedado. Se o ambiente host não for capaz de fornecer seqüências de caracteres com letras maiúsculas e minúsculas, a implementação deve garantir que as sequências sejam recebidas em letras minúsculas.
- Se o valor de
argc
for maior que zero, a cadeia apontada por argv[0]
representa o nome do programa; argv[0][0]
deve ser o caractere nulo se o nome do programa não estiver disponível no ambiente host. Se o valor argc
for maior que um, as cordas apontado por argv[1]
meio argv[argc-1]
representam os parâmetros do programa.
- Os parâmetros
argc
e argv
e as cordas apontado pela argv
matriz deve ser modificáveis pelo programa, e mantêm seus valores última armazenados entre inicialização do programa e encerramento 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.
Encerramento do programa em C99 ou C11
O valor retornado main()
é transmitido para o 'ambiente' de uma maneira definida pela implementação.
5.1.2.2.3 Finalização do programa
1 Se o tipo de retorno da main
função for compatível int
, um retorno da chamada inicial para a main
função é equivalente a chamar a exit
função com o valor retornado pela main
função como argumento; 11) alcançar o }
que encerra a
main
função retorna um valor 0. Se o tipo de retorno não for compatível int
, o status de finalização retornado ao ambiente host não é especificado.
11) De acordo com 6.2.4, a vida útil dos objetos com duração de armazenamento automático declarada main
terminará no primeiro caso, mesmo onde não teria no segundo.
Observe que 0
é obrigatório como 'sucesso'. Você pode usar EXIT_FAILURE
e EXIT_SUCCESS
de, <stdlib.h>
se preferir, mas 0 está bem estabelecido e 1. também. Consulte também Códigos de saída maiores que 255 - possíveis? .
No C89 (e, portanto, no Microsoft C), não há nenhuma declaração sobre o que acontece se a main()
função retornar, mas não especificar um valor de retorno; portanto, leva a um comportamento indefinido.
7.22.4.4 A exit
função
Finally5 Finalmente, o controle é retornado ao ambiente host. Se o valor de status
for zero ou EXIT_SUCCESS
, uma forma definida pela implementação do status de finalização bem-sucedida será retornada. Se o valor de status
for EXIT_FAILURE
, será retornada uma forma definida pela implementação do encerramento sem êxito do status . Caso contrário, o status retornado é definido pela implementação.
C ++ padrão - 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 função global chamada main, que é o início designado do programa. [...]
§ 2 Uma implementação não deve predefinir a função principal. Esta função não deve estar sobrecarregada. Ele deve ter um tipo de retorno do tipo int, mas, caso contrário, seu tipo é definido como implementação. Todas as implementações devem permitir as duas seguintes definições de main:
int main() { /* ... */ }
e
int main(int argc, char* argv[]) { /* ... */ }
Nesta última forma, argc
será o número de argumentos transmitidos ao programa a partir do ambiente em que o programa é executado. Se argc
for diferente de zero estes argumentos devem ser fornecidos no argv[0]
meio argv[argc-1]
como indicadores para os caracteres iniciais de cordas de vários bytes de terminação nula (NTMBSs) (17.5.2.1.4.2) e argv[0]
deve ser o ponteiro para o carácter inicial de uma NTMBS que representa o nome usado para invocar o programa ou ""
. O valor de argc
deve ser não negativo. O valor de argv[argc]
deve ser 0. [Nota: Recomenda-se que outros parâmetros (opcionais) sejam adicionados depois argv
. - end note]
§3 A função main
não deve ser usada dentro de um programa. A ligação (3.5) de main
é definida pela implementação. [...]
¶5 Uma declaração de retorno em main tem o efeito de deixar a função principal (destruindo qualquer objeto com duração de armazenamento automático) e chamar std::exit
com o valor de retorno como argumento. Se o controle chegar ao final do main sem encontrar uma declaração de retorno, o efeito é o de executar
return 0;
O padrão C ++ diz explicitamente "Ele [a função principal] deve ter um tipo de retorno do tipo int
, mas, caso contrário, seu tipo é definido pela implementação" 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 interromper uma implementação fora do padrão que 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 exit
função no padrão C11 (citado acima), além de uma nota de rodapé (que simplesmente documenta EXIT_SUCCESS
e EXIT_FAILURE
está definida in <cstdlib>
).
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 ponteiros para seqüências de caracteres, cada um dos quais é uma variável de ambiente que possui um nome, um sinal de igual e um valor (possivelmente vazio). Se você não usar isso, ainda poderá acessar o ambiente via ' extern char **environ;
'. Essa variável global é única entre as do POSIX, pois não possui um cabeçalho que a declare.
Isso é 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 função principal recebe um terceiro argumento,, char *envp[]
que aponta para uma matriz de ponteiros terminada em nulo para char
, cada um dos quais aponta para uma cadeia que fornece informações sobre o ambiente para esta execução do programa (5.1. 2.2.1)
Microsoft C
O compilador do Microsoft VS 2010 é interessante. O site diz:
A sintaxe da declaração para main é
int main();
ou, opcionalmente,
int main(int argc, char *argv[], char *envp[]);
Como alternativa, as funções main
e wmain
podem ser declaradas como retornando void
(sem valor de retorno). Se você declarar main
ou wmain
retornar nulo, não poderá 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
é declarado como void
, você deve usar a exit
função
Não está claro para mim o que acontece (qual código de saída é retornado ao pai ou SO) quando um programa void main()
sai - e o site da MS também fica silencioso.
Curiosamente, a MS não prescreve a versão de dois argumentos main()
exigida pelos padrões C e C ++. Apenas prescreve uma forma de três argumentos em que o terceiro argumento é char **envp
um ponteiro para uma lista de variáveis de ambiente.
A página da Microsoft também lista algumas outras alternativas - wmain()
que exigem amplas cadeias de caracteres e muito mais.
A versão do Microsoft Visual Studio 2005 desta página não lista void main()
como alternativa. As versões do Microsoft Visual Studio 2008 em diante.
Padrão C - Ambiente Independente
Como observado anteriormente, os requisitos acima se aplicam aos ambientes hospedados. Se você estiver trabalhando com um ambiente independente (que é a alternativa a um ambiente hospedado), o padrão terá muito menos a dizer. Para um ambiente independente, a função chamada na inicialização do programa não precisa ser chamada 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: autônomo e hospedado. Nos dois casos, a inicialização do programa ocorre quando uma função C designada é chamada pelo ambiente de execução. Todos os objetos com duração de armazenamento estático devem ser inicializados (definidos com seus valores iniciais) antes da inicialização do programa. A maneira e o momento dessa inicialização não são especificados. A finalização do programa retorna o controle para o ambiente de execução.
5.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 função chamada na inicialização do programa são definidos pela implementação. Quaisquer recursos de biblioteca disponíveis para um programa independente, além do conjunto mínimo exigido pela cláusula 4, são definidos 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 isso:
A5 Um programa estritamente conforme deve usar apenas os recursos do idioma e da biblioteca especificados nesta Norma. 3) Não deve produzir resultados dependentes de qualquer comportamento não especificado, indefinido ou definido pela implementação, e não deve exceder nenhum limite mínimo de implementação.
¶6 As duas formas de implementação em conformidade são hospedadas e independentes . Uma implementação hospedada em conformidade deve aceitar qualquer programa estritamente em conformidade. A implementação independente em conformidade aceitará qualquer programa rigorosamente de acordo em que o uso das características especificadas na cláusula biblioteca (cláusula 7) se limita ao conteúdo dos cabeçalhos padrão <float.h>
, <iso646.h>
, <limits.h>
, <stdalign.h>
,
<stdarg.h>
, <stdbool.h>
, <stddef.h>
, <stdint.h>
, e
<stdnoreturn.h>
. Uma implementação em conformidade pode ter extensões (incluindo funções adicionais da biblioteca), desde que não alterem o comportamento de nenhum programa estritamente em conformidade. 4)
¶7 Um programa em conformidade é aquele que é aceitável para uma implementação em conformidade. 5)
3) Um programa estritamente conforme pode usar recursos condicionais (consulte 6.10.8.3), desde que o uso seja protegido por uma diretiva de pré-processamento de inclusão condicional apropriada, usando a macro relacionada. Por exemplo:
#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
/* ... */
fesetround(FE_UPWARD);
/* ... */
#endif
4) Isso implica que uma implementação em conformidade não reserva outros identificadores além daqueles explicitamente reservados nesta Norma.
5) Os programas estritamente conformes devem ser portáteis ao máximo entre as implementações conformes. Os programas em conformidade podem depender de recursos não portáteis de uma implementação em conformidade.
É perceptível que o único cabeçalho necessário para um ambiente independente que realmente define quaisquer funções é <stdarg.h>
(e mesmo essas podem ser - e geralmente são - apenas macros).
C ++ padrão - ambiente independente
Assim como o padrão C reconhece o ambiente hospedado e independente, o mesmo ocorre com o padrão C ++. (Cotações da ISO / IEC 14882: 2011.)
1.4 Conformidade da 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, este Padrão Internacional define o conjunto de bibliotecas disponíveis. Uma implementação independente é aquela na qual 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 ao idioma (17.6.1.3).
A8 Uma implementação em conformidade pode ter extensões (incluindo funções adicionais da biblioteca), desde que não alterem o comportamento de nenhum programa bem formado. São necessárias implementações para diagnosticar programas que usam extensões mal formadas de acordo com esta Norma. Tendo feito isso, no entanto, eles podem compilar e executar esses programas.
Each9 Cada implementação deve incluir documentação que identifique todas as construções suportadas condicionalmente que não suportam e define todas as características específicas da localidade. 3
3) Esta documentação também define o comportamento definido pela implementação; ver 1.9.
17.6.1.3 Implementações autônomas [conformidade]
Dois tipos de implementações são definidos: hospedado e autônomo (1.4). Para uma implementação hospedada, este Padrão Internacional descreve o conjunto de cabeçalhos disponíveis.
Uma implementação independente possui um conjunto de cabeçalhos definido pela implementação. Este conjunto deve incluir pelo menos os cabeçalhos mostrados na Tabela 16.
A versão fornecido do cabeçalho <cstdlib>
declarará, pelo menos, as funções abort
, atexit
, at_quick_exit
, exit
, e quick_exit
(18.5). Os outros cabeçalhos 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)
<ciso646>
18.2 Types <cstddef>
18.3 Implementation properties <cfloat> <limits> <climits>
18.4 Integer types <cstdint>
18.5 Start and termination <cstdlib>
18.6 Dynamic memory management <new>
18.7 Type identification <typeinfo>
18.8 Exception handling <exception>
18.9 Initializer lists <initializer_list>
18.10 Other runtime support <cstdalign> <cstdarg> <cstdbool>
20.9 Type traits <type_traits>
29 Atomics <atomic>
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 também existem 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 afetam diretamente o texto principal do padrão. Dito isto, eles são fortemente indicativos do comportamento esperado; portanto, se o padrão incluir int main()
um exemplo, isso sugere que int main()
não é proibido, mesmo que não seja a notação preferida.
6.5.3.4 Os operadores sizeof
e_Alignof
...
¶8 EXEMPLO 3 Neste exemplo, o tamanho de uma matriz de comprimento variável é calculado e retornado de uma função:
#include <stddef.h>
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;
}