retorno - funciones predefinidas en c
¿Cuáles son las firmas válidas para la función main() de C? (5)
Estándar C
Para un entorno alojado (que es el normal), el estándar C99 dice:
5.1.2.2.1 Inicio del programa
La función llamada al inicio del programa se llama
main
. La implementación no declara ningún prototipo para esta función. Se definirá con un tipo de retorno deint
y sin parámetros:
int main(void) { /* ... */ }
o con dos parámetros (a los que se hace referencia aquí como
argc
yargv
, aunque se pueden usar los nombres, ya que son locales para la función en la que se declaran):
int main(int argc, char *argv[]) { /* ... */ }
o equivalente; 9) o de alguna otra manera definida por la implementación.
9) Por lo tanto,
int
puede ser reemplazado por un nombre typedef definido comoint
, o el tipo deargv
puede escribirse comochar **argv
, y así sucesivamente.
Estándar C ++
El estándar C ++ 98 dice:
3.6.1 Función principal [basic.start.main]
1 Un programa debe contener una función global llamada main, que es el inicio designado del programa. [...]
2 Una implementación no debe predefinir la función principal. Esta función no debe estar sobrecargada. Tendrá un tipo de retorno de tipo int, pero de lo contrario su tipo está definido por la implementación. Todas las implementaciones permitirán ambas de las siguientes definiciones de main:
int main() { /* ... */ }
y
int main(int argc, char* argv[]) { /* ... */ }
El estándar de C ++ dice explícitamente que "[la función principal] tendrá un tipo de retorno de tipo int, pero de lo contrario su tipo es implementación definida", y requiere las mismas dos firmas que el estándar C. Entonces, un ''void main ()'' no está directamente permitido por el estándar de C ++, aunque no hay nada que pueda hacer para detener una implementación no estándar que permita alternativas.
Extensión común
Clásicamente, los sistemas Unix admiten una tercera variante:
int main(int argc, char **argv, char **envp) { ... }
El tercer argumento es una lista de punteros terminados en nulo para cadenas, cada una de las cuales es una variable de entorno que tiene un nombre, un signo igual y un valor (posiblemente vacío). Si no lo usa, puede acceder al entorno a través del entorno '' extern char **environ;
''. Durante mucho tiempo, no tenía un encabezado que lo declarara, pero el estándar POSIX 2008 ahora requiere que se declare en <unistd.h>
.
Esto es reconocido por el estándar C como una extensión común, documentada en el Anexo J:
J.5.1 Argumentos del entorno
¶1 En un entorno alojado, la función principal recibe un tercer argumento,
char *envp[]
, que apunta a un conjunto de punteros terminados en nulo enchar
, cada uno de los cuales apunta a una cadena que proporciona información sobre el entorno para esta ejecución del programa (5.1.2.2.1).
Microsoft C
El compilador de Microsoft VS 2010 es interesante. El sitio web dice:
La sintaxis de declaración para main es
int main();
u, opcionalmente,
int main(int argc, char *argv[], char *envp[]);
Alternativamente, las funciones
main
ywmain
se pueden declarar comowmain
void
(sin valor de retorno). Si declaramain
owmain
comowmain
void, no puede devolver un código de salida al proceso principal o al sistema operativo mediante el uso de una declaración return. Para devolver un código de salida cuandomain
owmain
se declaravoid
, debe usar la función deexit
.
No está claro para mí qué sucede (qué código de salida se devuelve al padre o al o) cuando un programa con void main()
sale, y el sitio web de MS también está en silencio.
Curiosamente, MS no prescribe la versión de dos argumentos de main()
que requieren los estándares C y C ++. Solo prescribe una forma de tres argumentos donde el tercer argumento es char **envp
, un puntero a una lista de variables de entorno.
La página de Microsoft también enumera otras alternativas: wmain()
que toma cadenas de caracteres anchas, y algunas más.
La versión Microsoft VS 2005 de esta página no enumera void main()
como alternativa. Las versions de Microsoft VS 2008 en adelante lo hacen.
¿Cuáles son realmente las firmas válidas para la función principal en C? Lo sé:
int main(int argc, char *argv[])
¿Hay otros válidos?
El estándar actual como en el momento de esta respuesta (C11) menciona explícitamente estos dos:
int main(void);
int main(int argc, char* argv[]);
aunque menciona la frase "o equivalente" con la siguiente nota al pie:
Por lo tanto,
int
puede reemplazarse por un nombretypedef
definido comoint
, o el tipo deargv
puede escribirse comochar ** argv
, y así sucesivamente.
Además, también proporciona más posibilidades (definidas por la implementación).
La sección correspondiente (sección 5.1.2.2.1 en C11, pero este aspecto particular no ha cambiado desde C99) dice:
La función llamada al inicio del programa se llama main. La implementación no declara ningún prototipo para esta función. Se definirá con un tipo de retorno de int y sin parámetros:
int main(void) { /* ... */ }
o con dos parámetros (a los que se hace referencia aquí como argc y argv, aunque se pueden usar los nombres, ya que son locales para la función en la que se declaran):
int main(int argc, char *argv[]) { /* ... */ }
o equivalente; o de alguna otra manera definida por la implementación.
Si se declaran, los parámetros de la función principal obedecerán las siguientes restricciones:
El valor de
argc
debe ser no negativo.
argv[argc]
será un puntero nulo.Si el valor de argc es mayor que cero, los miembros de la matriz
argv[0]
aargv[argc-1]
inclusive contendrán punteros a las cadenas, que reciben los valores definidos por la implementación por el entorno de host antes del inicio del programa. La intención es suministrar a la información del programa determinada antes del inicio del programa desde otro lugar en el entorno alojado. Si el entorno de host no es capaz de suministrar cadenas con letras en mayúsculas y minúsculas, la implementación se asegurará de que las cadenas se reciban en minúsculas.Si el valor de
argc
es mayor que cero, la cadena apuntada porargv[0]
representa el nombre del programa;argv[0][0]
será el carácter nulo si el nombre del programa no está disponible desde el entorno host. Si el valor deargc
es mayor que uno, las cadenas apuntadas porargv[1]
aargv[argc-1]
representan los parámetros del programa.Los parámetros
argc
yargv
y las cadenas apuntadas por la matrizargv
serán modificables por el programa y conservarán sus últimos valores almacenados entre el inicio del programa y la terminación del programa.
Tenga en cuenta que esto es para un entorno alojado, los que normalmente ve en los programas C. Un entorno autónomo (como un sistema integrado) está mucho menos restringido, como se indica en 5.1.2.1 del mismo estándar:
En un entorno independiente (en el que la ejecución del programa C puede tener lugar sin ningún beneficio de un sistema operativo), el nombre y el tipo de la función llamada al inicio del programa están definidos por la implementación. Cualquier instalación de biblioteca disponible para un programa independiente, que no sea el conjunto mínimo requerido por la cláusula 4, está definida por la implementación.
POSIX admite execve()
, que a su vez admite
int main(int argc, char *argv[], char *envp[])
El argumento agregado es el entorno, es decir, una matriz de cadenas de la forma NAME = VALUE.
http://en.wikipedia.org/wiki/Main_function_(programming)#C_and_C.2B.2B
Además de lo usual int main(int argc, char *argv[])
y POSIX int main(int argc, char **argv, char **envp)
, en Mac OS X también es compatible
int main(int argc, char* argv[], char* envp[], char* apple[]);
Por supuesto, es solo para Mac.
En Windows hay
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);
como la variante Unicode (en realidad, de caracteres anchos). Por supuesto, también está WinMain
.
int main(void)
Bajo algunos sistemas operativos (por ejemplo, Windows) también es válido:
int main(int argc, char **argv, char **envp)
donde envp
da un ambiente, de lo contrario accesible a través de getenv()