2010-10-08 17 views

Respuesta

5

función con el tipo de retorno vacío no devuelve ningún valor. No hay nada ilógico si tenemos en cuenta la pila de llamadas es el siguiente:

OS -> D runtime -> main 

La principal función es invocada por el sistema de tiempo de ejecución D, que reconoció que la principal función devuelve nada - y en este caso el éxito de retorno al sistema operativo. En caso de que la función principal se defina con el tipo de retorno int, entonces el tiempo de ejecución D retorna al valor del sistema operativo devuelto por la función principal.

+0

@Michal He aceptado su respuesta porque es la más clara. Pero creo que si ves main con void, en el mejor de los casos es confuso si alguien dice que devuelve algo. No es la mejor opción de parte D en mi opinión. –

+2

Es un poco engañoso, pero no más que algo como "' main' devuelve un valor para el sistema operativo ". Que es lo que indica la documentación para la mayoría de los idiomas :) en casi todos los términos :) Siempre hay una capa intermedia para 1) manejar las interacciones específicas del sistema operativo y 2) aplicar la semántica del lenguaje. – shambulator

+0

@shambulator pero el valor devuelto por main (en C++) es el valor devuelto al sistema, así que para mí como para "un usuario de un idioma" no importa realmente qué otras capas estarán allí - estoy afirmando claramente que desde el último punto que tengo el control sobre (principal) mi programa devuelve los principales retornos y teniendo el vacío como un tipo de devolución y aún devolver algo "implícitamente" es simplemente una mala idea. Para mí de todos modos. Y cuando dices que no es cierto que el principal valor de retorno para el sistema operativo no es cierto porque un principal es el primer punto (o el último) depende de cómo veas esto - –

1

Si se define la función como

int main(...); 

entonces el valor de retorno, que se puede obtener (en bash) usando

echo $? 

será lo que retorno de la función. Si usted no devuelve nada, o definir su función como main

void main(...); 

entonces el estado de salida del comando no está definido. Por alguna razón (no puedo encontrar ninguna documentación sobre esto) siempre hay 200 en mi sistema.

+0

@Delan pero si la función se define con el vacío como un retorno de tipo no debería devuelve nada, ni siquiera 200. El problema que tengo con esto es que a pesar de vacío es tan un retorno tipo esta función siempre devuelve algo y eso para mí es ilógico, ¿estarías de acuerdo conmigo? –

+2

La * función * no devuelve nada si usa 'void main'. Una vez que 'main' regrese, el * D * runtime support * le da un código de salida de proceso al sistema operativo, sin importar qué forma use. Si usa 'int main', el valor que devuelve es el que se devuelve al sistema operativo. El sistema operativo no sabe ni le importa qué idioma usó; la existencia de un código de salida no depende de eso. – shambulator

+0

@shambulator no está de acuerdo, Andrei Alexandrescu dice: "En D, void main() devuelve cero (éxito) en el sistema operativo en retorno normal y no nulo en caso de excepción". y eso para mí es altamente ilógico, ¿estás de acuerdo conmigo? –

6

Hay varias firmas posibles para main():

void main() 
void main(string[] args) 
void main(char[][] args) 
void main(wstring[] args) 
void main(wchar[][] args) 
void main(dstring[] args) 
void main(dchar[][] args) 
int main() 
int main(string[] args) 
int main(char[][] args) 
int main(wstring[] args) 
int main(wchar[][] args) 
int main(dstring[] args) 
int main(dchar[][] args) 

Si int es el tipo de retorno, entonces es más o menos lo mismo en C o C++. El valor que devuelve es lo que ve el OS/shell. Si se lanza una excepción, se imprime un seguimiento de pila, y el sistema operativo/shell ve un valor distinto de cero. No sé de qué se trata Puede variar según el tipo de excepción.

Si void es el tipo de devolución, el sistema operativo/shell ve 0. Si se produce una excepción, se imprime un seguimiento de pila y el sistema operativo ve un valor distinto de cero. De nuevo, no sé de qué se trata.

Básicamente, tener void principal no le permite preocuparse por devolver un valor al sistema operativo/shell. Muchos programas no se preocupan en lo más mínimo por devolver el éxito o el fracaso al SO/shell. Entonces, con el vacío, el OS/shell siempre obtiene 0 a menos que se produzca una excepción, lo cual tiene sentido, ya que la única falla del programa en ese punto es si se escapa una excepción main(). Si do se preocupan por devolver el éxito o el fracaso al OS/shell, simplemente use una de las versiones que devuelve int.

La plétora de firmas debido a diferentes tipos de cadenas es que puede utilizar prácticamente cualquiera de los posibles tipos de cadenas como la entrada a main(). main() y main(string[] args) son probablemente los más utilizados.

12

Lo que dice Alexandrescu es simplemente una abreviatura del código de salida que describí. El cero o no cero devuelto al sistema operativo es un código de salida de proceso (independiente del idioma), no un valor de retorno de función. El sistema operativo no llama directamente al main, y main no regresa directamente al sistema operativo.El compilador D inserta el código de inicio y cierre en su programa para manejar estas interacciones con el SO, al igual que casi todos los demás compiladores para otros lenguajes. Al inicio, por ejemplo, este código repetitivo utiliza algún mecanismo dependiente del sistema operativo para obtener los argumentos de la línea de comandos y los coloca en una matriz D string[] para pasar al main. Al apagar, utiliza el valor de retorno de int main para el código de salida o, para void main, usa su propio valor (0 para el éxito, distinto de cero para excepción no controlada).

En pseudocódigo:

// Generated by compiler 
void _realMain() 
{ 
    // OS-dependent; probably calls GetCommandLineW 
    // and CommandLineToArgvW on Windows, for example 
    string[] cmdLineArgs = createArgArray(); 

    int exitCode = 0; // Assume success 
    try 
    { 
     // static if selects only one call to main for compilation, 
     // depending on main's return type. 

     // If main has been written to return int, use its value for the exit code 
     static if (main returns int) 
      exitCode = main(cmdLineArgs); 
     // If main has been declared void, just run it and keep the exit code of 0 
     else 
      // void main: *doesn't return anything* 
      main(cmdLineArgs); 
    } 
    catch 
    { 
     // Unhandled exception results in non-zero exit code 
     exitCode = 1; 
     printStackTrace(); 
    } 

    // OS-dependent process shutdown function. 
    // This is where the exit code is "returned" to the OS. 
    // Note it *does not* use the return keyword to do so. 
    // Calling the OS's function to kill the current process 
    // does not return, because the process is dead by the 
    // time the function has finished! 
    exitProcess(exitCode); 
    // In particular, no code *after* the exitProcess line will run. 
} 
Cuestiones relacionadas