How can D return 0 on success and non-zero on failure if main is not valid?

The main function is defined in D:

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

I know for sure that this function returns zero on success and is not equal to zero on failure, and yet it is defined as not returning anything. What is its logic?

+6
d
source share
4 answers

A function with a return type of void does not return any value. There is nothing illogical if you think the call stack looks like this:

 OS -> D runtime -> main 

The main function is called by the D runtime system, which recognizes that the main function does not return anything - and in this case, returns the success of the OS. If the main function is defined with the return type int, then the runtime D returns to the OS value returned by the main function.

+5
source share

What Alexandrescu says simply shortens the exit code I described. A zero or non-zero return to the OS is the process exit code (agnostic language), and not the return value of the function. The OS does not directly call main , and main does not directly return to the OS. Compiler D inserts start-up and shutdown code into its program to handle these interactions with the OS, like many other compilers for other languages. When launched, for example, this template code uses some OS-dependent mechanism to receive command line arguments and puts them in the D string[] array to go 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 the unhandled exception).

In pseudo code:

 // 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 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 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. } 
+12
source share

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 is almost the same as in C or C ++. The return value is what the OS / shell sees. If an exception is thrown, a stack trace is printed, and OS / shell sees a nonzero value. I do not know what is this. It may vary depending on the type of exception.

If void is the return type, then OS / shell sees 0. If an exception is thrown, then the stack trace is traced, and the OS sees a non-zero value. Again, I do not know what it is.

In fact, the presence of void main allows you not to worry about returning the value of the OS / shell. Many programs are by no means connected with the return of success or the failure of the OS / shell. Thus, with void, OS / shell always gets 0 if no exception is thrown - which makes sense, since the only program failure at this point is the exception if the exception throws main() . If you care about returning success or failure in OS / shell, you simply use one of the versions that returns an int.

A lot of the signature due to the different types of strings is that you can use almost any of the possible types of strings as input to main() . main() and main(string[] args) are probably the most commonly used.

+6
source share

If you define a function as

 int main(...); 

the return value you can get (in bash) using

 echo $? 

will be what you return from the function. If you do not 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 is always 200 on my system.

+1
source share

All Articles