2010-10-08 21 views

risposta

5

La funzione con tipo di reso vuoto non restituisce alcun valore. Non c'è niente di illogico se si considera stack di chiamate simile al seguente:

OS -> D runtime -> main 

La funzione principale viene richiamato dal sistema di runtime D, che ha riconosciuto che la funzione principale non restituisce nulla - e in questo caso il ritorno successo al sistema operativo. Nel caso in cui la funzione principale sia definita con il tipo restituito int, il runtime D ritorna al valore OS restituito dalla funzione principale.

+0

@Michal Ho accettato la tua risposta perché è la più chiara. Ma penso che se vedi main con void è nel migliore dei casi confondere se qualcuno dice che restituisce qualcosa. Non è la scelta migliore sulla parte D secondo me. –

+2

È un po 'fuorviante, ma non più di qualcosa come "main" restituisce un valore al sistema operativo ". Qual è il contenuto della documentazione per la maggior parte delle lingue, in questi termini :) C'è sempre un livello intermedio a 1) gestire le interazioni specifiche del sistema operativo e 2) applicare la semantica del linguaggio. – shambulator

+0

@shambulator ma il valore restituito da main (in C++) è il valore restituito al sistema, quindi per me come per "un utente di una lingua" non importa davvero quali altri livelli ci saranno - dichiaro chiaramente che dall'ultimo punto ho il controllo su (main) il mio programma restituisce i principali rendimenti e avendo vuoto come tipo di ritorno e restituendo qualcosa "implicitamente" è solo una cattiva idea. Per me comunque. E quando stai dicendo che non è vero che il valore di ritorno principale al sistema operativo non è vero perché un main è il primo punto (o l'ultimo) dipende da come lo guardi - –

1

Se si definisce la funzione come

int main(...); 

allora il valore di ritorno, che si può ottenere (in bash) utilizzando

echo $? 

sarà tutto ciò che si torna dalla funzione. Se non riesci a tornare nulla, o si definisce la funzione main come

void main(...); 

quindi lo stato di uscita del comando non è definito. Per qualche ragione (non riesco a trovare alcuna documentazione su questo) è sempre 200 sul mio sistema.

+0

@Delan ma se la funzione è definita con vuoto come un ritorno di tipo non dovrebbe restituire nulla, nemmeno 200. Il problema che ho con questo è che, anche se nulla è come un tipo di ritorno questa funzione restituisce sempre qualcosa e che per me è illogico, sei d'accordo con me? –

+2

La * funzione * non restituisce nulla se si utilizza 'void main'. Una volta restituito 'main', il supporto * D runtime fornisce un codice di uscita del processo al sistema operativo, indipendentemente dal modulo utilizzato. Se si utilizza 'int main', il valore che si restituisce è quello passato al sistema operativo. Il sistema operativo non sa o si preoccupa di quale lingua hai usato; l'esistenza di un codice di uscita non dipende da questo. – shambulator

+0

@shambulator non sono d'accordo, Andrei Alexandrescu dice: "In D, void main() restituisce zero (successo) al sistema operativo con ritorno normale e non zero su eccezione." e questo per me è altamente illogico, sei d'accordo con me? –

6

Ci sono diversi possibili firme per 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) 

Se int è il tipo di ritorno, allora è praticamente la stessa cosa in C o C++. Il valore restituito è ciò che vede il sistema operativo/shell. Se viene generata un'eccezione, viene stampata una traccia dello stack e il sistema operativo/shell vede un valore diverso da zero. Non so cosa sia. Può variare in base al tipo di eccezione.

Se vuoto è il tipo restituito, il sistema operativo/shell visualizza 0. Se viene generata un'eccezione, viene stampata una traccia dello stack e il sistema operativo visualizza un valore diverso da zero. Di nuovo, non so cosa sia.

Essenzialmente, con void principale non ti devi preoccupare di restituire un valore all'OS/shell. Molti programmi non sono minimamente interessati al ritorno o al fallimento del sistema operativo/shell. Quindi, con void, il sistema operativo/shell ottiene sempre 0 a meno che non venga lanciata un'eccezione, il che ha senso, poiché l'unico errore del programma a quel punto è se un'eccezione fuoriesce dallo main(). Se si fare si preoccupa di restituire il successo o l'errore al sistema operativo/shell, quindi è sufficiente utilizzare una delle versioni che restituisce int.

La pletora di firme a causa di diversi tipi di stringhe è che è possibile utilizzare praticamente tutti i tipi di stringa possibili come input per main(). main() e main(string[] args) sono probabilmente i più usati.

12

Quello che Alexandrescu sta dicendo è semplicemente una scorciatoia per il codice di uscita che ho descritto. Lo zero o il diverso zero restituito al sistema operativo è un codice di uscita del processo (indipendente dalla lingua), non un valore restituito dalla funzione. Il sistema operativo non chiama direttamente main e main non torna direttamente al sistema operativo.Il compilatore D inserisce il codice di avvio e di arresto nel programma per gestire queste interazioni con il sistema operativo, analogamente a quasi tutti gli altri compilatori per altre lingue. All'avvio, ad esempio, questo codice boilerplate utilizza un meccanismo dipendente dal sistema operativo per ottenere gli argomenti della riga di comando e li inserisce in una serie D string[] da passare a main. All'arresto, utilizza il valore restituito da int main per il codice di uscita oppure, per void main, utilizza il proprio valore (0 per il successo, diverso da zero per l'eccezione non gestita).

In pseudocodice:

// 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. 
} 
Problemi correlati