如果main无效,D如何在成功时返回0并在失败时返回非零?

时间:2010-10-08 07:54:49

标签: d

在D中,定义了main函数:

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

}  

我确信这个函数在成功时返回零,在失败时返回非零,但它被定义为不返回任何内容。它背后的逻辑是什么?

4 个答案:

答案 0 :(得分:13)

Alexandrescu所说的只是我描述的退出代码的简写。返回到操作系统的零或非零是一个(语言无关的)进程退出代码,而不是函数返回值。操作系统不直接调用mainmain不直接返回操作系统。 D编译器在程序中插入启动和关闭代码来处理与操作系统的这些交互,几乎所有其他语言的编译器也是如此。例如,在启动时,此样板代码使用一些依赖于操作系统的机制来获取命令行参数,并将它们放入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.
}

答案 1 :(得分:6)

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 ++中几乎相同。您返回的值是OS / shell看到的值。如果抛出异常,则打印堆栈跟踪,并且OS / shell看到非零值。我不知道它是什么。它可能因异常类型而异。

如果void是返回类型,则OS / shell看到0.如果抛出异常,则打印堆栈跟踪,并且OS看到非零值。再说一遍,我不知道它是什么。

基本上,拥有void main允许您不必担心将值返回给OS / shell。许多程序对于返回OS / shell的成功或失败一点也不关心。因此,使用void,除非抛出异常,否则OS / shell总是为0 - 这是有道理的,因为此时唯一的程序失败是异常逃脱main()。如果你关心返回OS / shell的成功或失败,那么你只需使用一个返回int的版本。

由于不同的字符串类型而导致的过多签名是您可以使用几乎任何可能的字符串类型作为main()的输入。 main()main(string[] args)可能是最常用的。

答案 2 :(得分:5)

具有void返回类型的

函数不返回任何值。当您认为调用堆栈看起来像这样时,没有什么不合逻辑的:

OS -> D runtime -> main

主要功能由D运行时系统调用,它识别出main函数什么都不返回 - 在这种情况下返回OS的成功。如果main函数定义为返回类型int,则D运行时返回main函数返回的OS值。

答案 3 :(得分:1)

如果将功能定义为

int main(...);

然后返回值,你可以使用

获得(在bash中)
echo $?

将是您从函数返回的任何内容。如果您未返回任何内容,或者将main函数定义为

void main(...);

然后命令的退出状态是未定义的。出于某种原因(我找不到任何相关的文档)它在我的系统上总是200。