En muchos lenguajes como C, C ++ y Java, el main
método / función tiene un tipo de retorno de void
o int
, pero no double
o String
. ¿Cuáles podrían ser las razones detrás de eso?
Sé un poco que no podemos hacer eso porque main
es invocado por la biblioteca de tiempo de ejecución y espera alguna sintaxis como int main()
o int main(int,char**)
así, tenemos que apegarnos a eso.
Entonces mi pregunta es: ¿por qué main
tiene la firma de tipo que tiene, y no una diferente?
Respuestas:
El valor de retorno de
main
se debe pasar al sistema operativo ( cualquier sistema operativo) de una manera única y coherente. La información que el sistema operativo necesita saber es "¿el programa finalizó correctamente o hubo un error?"Si se trata de una cadena, la respuesta se vuelve difícil en diferentes idiomas. Las partes internas de una cadena Pascal (primer byte es la longitud) y una cadena FORTRAN (fija, rellenada con algún valor) y una cadena C (terminada en nulo) son todas diferentes. Esto haría que devolver un valor constante al sistema operativo fuera un desafío. Suponiendo que esto se resolvió, ¿qué haría para responder la pregunta que el sistema operativo tenía sobre el programa? Las comparaciones de cadenas están llenas de errores ("éxito" versus "éxito"), y aunque el error puede ser más útil para un humano, es más difícil de manejar para el sistema operativo u otro programa (shell). También hubo diferencias significativas incluso en las propias cadenas: EBCDIC (con todas sus páginas de códigos) frente a ASCII.
Los flotantes y los dobles no proporcionan ningún valor adicional sobre el entero para comunicar los datos al sistema operativo (y al shell). En su mayor parte, ninguna de estas partes de la computadora trata con números de coma flotante. Los dobles tampoco son enumerables, lo que dificulta las comparaciones. Al no ser enumerables, informan cuál fue el error (suponiendo que haya elegido un valor particular para el éxito). Una vez más, los puntos flotantes no son consistentes: un flotante en una máquina de 8 bits era diferente del flotante en una máquina de 16 bits y una de 32 bits (y esos son solo los 'normales', incluso dentro de IBM, el punto flotante no estaba estandarizado entre máquinas del mismo fabricante hasta la década de 1980). Y luego tienes computadoras decimales vs. binarias. Los valores de coma flotante no son consistentes y no devuelven datos significativos.
Eso realmente nos deja con el byte y el entero como opciones. La convención que se estableció fue '0' fue un éxito, y cualquier otra cosa fue un error. Un número entero da más espacio que un byte para informar el error. Se puede enumerar (el retorno de 1 significa XYZ, el retorno de 2 significa ABC, el retorno de 3, significa DEF, etc.) o usarse como indicadores (
0x0001
significa que esto falló,0x0002
significa que falló,0x0003
significa tanto esto como aquello que falló). Limitar esto a solo un byte podría quedarse sin banderas (solo 8), por lo que la decisión fue probablemente usar un número entero.fuente
main()
se invoca de diferentes maneras en diferentes sistemas operativos. En C, ¿cómo se llama inicialmente el método main ()? entra en esto.main
, a diferencia de otras funciones en cualquier programa, no es parte de un protocolo definido por el programador, sino el protocolo utilizado para interactuar con el host (SO). No puedes elegirlo porque nunca fue tuyo. En un nivel más pragmático, UNIX espera que un proceso devuelva un int, por lo que el protocolo C-a-UNIX hace exactamente eso. Se puede hacer un argumento análogo para pasar argumentos: si C se hubiera inventado para un sistema operativo / host que pasara solo números como argumentos (por ejemplo, sin línea de comandos), los argumentos serían ints en lugar de cadenas.Pues podría .
Por ejemplo, en el dialecto de C utilizado en el sistema operativo del Plan 9
main
normalmente se declara como unavoid
función, pero el estado de salida se devuelve al entorno de llamada al pasar un puntero de cadena a laexits()
función. La cadena vacía denota éxito, y cualquier cadena no vacía denota algún tipo de falla. Esto podría haberse implementado almain
devolver unchar*
resultado.Y sin duda sería posible implementar un sistema con una
float
odouble
estado de salida.¿Entonces por qué
int
? Es solo una cuestión de convención, y hay un gran valor para que los sistemas operativos y los programas que se ejecutan bajo ellos obedezcan una convención común.La convención de Unix es usar un código de estado entero, con 0 que denota éxito y falla que no denota cero (porque típicamente solo hay una forma de tener éxito, pero múltiples formas de fallar). No sé si esa convención se originó con Unix; Sospecho que vino de sistemas operativos anteriores.
La coma flotante sería una convención más difícil, porque (a) el soporte de coma flotante no es universal, (b) es más difícil definir un mapeo entre los valores de coma flotante y las condiciones de error, (c) diferentes sistemas usan diferentes flotantes. representaciones de puntos, y (d) simplemente imagine la diversión de localizar un error de redondeo en el estado de salida de su programa. Los enteros, por otro lado, se prestan muy bien para enumerar códigos de error.
El Plan 9, como mencioné, usa cadenas, pero eso impone cierta complejidad para la administración de la memoria, la codificación de caracteres, etc. Era, hasta donde yo sé, una idea nueva cuando el Plan 9 lo implementó, y no reemplazó el existente. Convención generalizada.
(Por cierto, en C ++ solo
main
puede regresar , y en C está permitido solo si el compilador lo admite específicamente. Muchos compiladores no se quejan muy alto si escribe , pero es solo una ligera exageración decir que está mal ).int
void main
void main
fuente
El valor devuelto por el método principal es un "código de salida". La aplicación que llama (normalmente bash) la usa para probar si el programa finalizó como se esperaba. Devolver un número entero es la forma más fácil de hacerlo en el nivel del sistema operativo. Double no tiene sentido para el código de error y una cadena es difícil de mantener en el nivel del sistema operativo (no hay GC).
fuente
main debe devolver el estado del programa que se ejecuta. Si se ejecuta con éxito (devuelve 0 que es EXIT_SUCCESS) o no (devuelve 1 significa EXIT_FAILURE) cualquier número distinto de cero transmite el mismo significado pero cero indica que no hay errores o ejecución exitosa.
fuente