问题
In D, the main
function is defined:
void main(/*perhaps some args but I do not remember*/)
{
}
I know for sure that this function returns zero on success and non-zero on failure and yet it is defined as not returning anything. What is the logic behind it?
回答1:
function with void return type does not return any value. There is nothing illogical when you consider call stack looks like this:
OS -> D runtime -> main
The main function is invoked by D runtime system, which recognized that the main function returns nothing - and in this case return success to the OS. In case the main function is defined with return type int, then the D runtime return to OS value returned by main function.
回答2:
What Alexandrescu is saying is simply shorthand for the exit code I described. The zero or nonzero returned to the OS is a (language-agnostic) process exit code, not a function return value. The OS doesn't call main
directly, and main
doesn't return directly to the OS. The D compiler inserts startup and shutdown code in your program to handle these interactions with the OS, as do pretty much all other compilers for other languages. On startup, for instance, this boilerplate code uses some OS-dependent mechanism to get the command-line arguments, and puts them into a D string[]
array to pass to main
. On shutdown, it uses the return value from int main
for the exit code, or, for void main
, uses its own value (0 for success, nonzero for unhandled exception).
In pseudocode:
// 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.
}
回答3:
There are several possible signatures for 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)
If int is the return type, then it's pretty much the same is in C or C++. The value that you return is what the OS/shell sees. If an exception is thrown, then a stack trace is printed, and the OS/shell sees a non-zero value. I don't know what it is. It may vary by exception type.
If void is the return type, then the OS/shell sees 0. If an exception is thrown, then a stack trace is printed, and the OS sees a non-zero value. Again, I don't know what it is.
Essentially, having void main allows you to not worry about returning a value to the OS/shell. Many programs are not in the least bit concerned with returning success or failure to the OS/shell. So, with void, the OS/shell always gets 0 unless an exception is thrown - which makes sense, since the only program failure at that point is if an exception escapes main()
. If you do care about returning success or failure to the OS/shell, then you simply use one of the versions that returns int.
The plethora of signatures due to different string types is that you can use pretty much any of the possible string types as the input to main()
. main()
and main(string[] args)
are probably the most commonly used though.
回答4:
If you define the function as
int main(...);
then the return value, that you can get (in bash) using
echo $?
will be whatever you return from the function. If you don't return anything, or you define your main
function as
void main(...);
then the exit status of the command is undefined. For some reason (I can't find any documentation on this) it's always 200 on my system.
来源:https://stackoverflow.com/questions/3888661/how-can-d-return-0-on-success-and-non-zero-on-failure-if-main-is-void