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

The*_* do 6 d

在D中,main定义了函数:

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

}  
Run Code Online (Sandbox Code Playgroud)

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

sha*_*tor 13

Alexandrescu所说的只是我所描述的退出代码的简写.返回到操作系统的零或非零是一个(语言无关的)进程退出代码,而不是函数返回值.操作系统不main直接调用,main也不直接返回操作系统.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.
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*vis 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)
Run Code Online (Sandbox Code Playgroud)

如果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)可能是最常用的.


Mic*_*ich 5

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

OS -> D runtime -> main
Run Code Online (Sandbox Code Playgroud)

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

  • 这有点误导,但不比"main"给操作系统返回一个值更重要.这就是大多数语言的文档所指出的,几乎就是那些术语:)总是有一个中间层来1)处理特定于OS的交互和2)强制语言语义. (2认同)