Как D может вернуть 0 в случае успеха и ненулевое значение в случае неудачи, если main не имеет значения? - PullRequest
6 голосов
/ 08 октября 2010

В D определена функция main:

void main(/*perhaps some args but I do not remember*/)
{

}  

Я точно знаю, что эта функция возвращает ноль при успехе и ненулевое значение при ошибке, но она определена как ничего не возвращающая.Какая логика стоит за этим?

Ответы [ 4 ]

13 голосов
/ 08 октября 2010

То, что говорит Александреску, является просто сокращением для кода выхода, который я описал.Ноль или ненулевое значение, возвращаемое ОС, является кодом завершения процесса (не зависит от языка), а не значением возврата функции.ОС не вызывает main напрямую, а main не возвращает напрямую в ОС.Компилятор D вставляет код запуска и завершения в вашу программу для обработки этих взаимодействий с ОС, как и почти все другие компиляторы для других языков.Например, при запуске этот стандартный код использует некоторый OS-зависимый механизм для получения аргументов командной строки и помещает их в массив D string[] для передачи в main.При завершении работы он использует возвращаемое значение из int main для кода выхода или, для void main, использует свое собственное значение (0 для успеха, ненулевое для необработанного исключения).

В псевдокоде:

// 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.
}
6 голосов
/ 08 октября 2010

Существует несколько возможных сигнатур для 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)

Если тип int - это тип возвращаемого значения, то он почти такой же, как в C или C ++.Возвращаемое вами значение - это то, что видит ОС / оболочка.Если выдается исключение, то выводится трассировка стека, и ОС / оболочка видит ненулевое значение.Я не знаю что это.Это может варьироваться в зависимости от типа исключения.

Если тип возвращаемого значения void, то ОС / оболочка видит 0. Если выброшено исключение, то выводится трассировка стека, а ОС видит ненулевое значение,Опять же, я не знаю, что это такое.

По сути, наличие void main позволяет вам не беспокоиться о возвращении значения в ОС / оболочку.Многие программы нисколько не заботятся о возврате успеха или неудачи в ОС / оболочке.Таким образом, с помощью void ОС / оболочка всегда получает 0, если не выдается исключение - что имеет смысл, поскольку единственная программная ошибка в этой точке - это исключение main().Если вы do заботитесь о возвращении успеха или неудачи в ОС / оболочку, то вы просто используете одну из версий, которая возвращает int.

Изобилие подписей из-за различных типов строк состоит в том, чтоВы можете использовать практически любой из возможных типов строк в качестве входных данных для main().main() и main(string[] args), вероятно, наиболее часто используемые.

5 голосов
/ 08 октября 2010
Функция

с возвращаемым типом void не возвращает никакого значения.Нет ничего нелогичного, если учесть, что стек вызовов выглядит следующим образом:

OS -> D runtime -> main

Основная функция вызывается системой времени выполнения D, которая распознала, что основная функция ничего не возвращает, и в этом случае возвращает успех ОС.,Если основная функция определена с типом возврата int, то время выполнения D возвращает значение ОС, возвращаемое основной функцией.

1 голос
/ 08 октября 2010

Если вы определите функцию как

int main(...);

, то возвращаемое значение, которое вы можете получить (в bash) с помощью

echo $?

, будет тем, что вы вернете из функции.Если вы ничего не возвращаете или определяете свою функцию main как

void main(...);

, то статус выхода команды не определен.По какой-то причине (я не могу найти никакой документации по этому вопросу) в моей системе всегда 200.

...