How does "return 0;" work and why is it necessary?

  • C/++/#
  • Thread starter dect117
  • Start date
  • #1
25
1

Main Question or Discussion Point

My understanding is that if the main function's return type is an integer, i.e. it looks like this: int main () {...}, then "return 0;" must be written otherwise the function won't work. My professor said that the exception would be if you wrote "void" in the parenthesis like this: "int main (void)". However, this piece of code works just fine without "void" or "return 0;". Why?
Code:
#include <stdio.h>
int main () {
    printf ("Hello!");
}
 

Answers and Replies

  • #2
phinds
Science Advisor
Insights Author
Gold Member
2019 Award
15,912
5,600
In C, main is an integer function and functions are REQUIRED to have a proper return value but most (probably all) compilers make an exception for main and there's an effective default "return 0" coded at the end. This is the standard return for signalling to the calling program that the function worked just fine. You don't normally think of main as HAVING a calling program but they very well can if they are invoked by another process and that other process will want to know if the function worked.

To get technical, main ALWAYS has a calling program and it's the operating system.
 
  • #3
25
1
I thought that there must be an invisible "return 0;" there. Does the returned integer have to be zero? What if it isn't? I just wrote a simple program without writing return at the end and it says that the "Process exited after 2.16 seconds with return value 10."
 
  • #4
phinds
Science Advisor
Insights Author
Gold Member
2019 Award
15,912
5,600
I thought that there must be an invisible "return 0;" there. Does the returned integer have to be zero? What if it isn't? I just wrote a simple program without writing return at the end and it says that the "Process exited after 2.16 seconds with return value 10."
?
What compiler are you using? If you don't put a return a C compiler is supposed to put a default return 0. As I said, functions are REQUIRED to have a return (but it doesn't have to be zero --- that would be pointless). In some languages such as VB (but not C), there are "subroutines" and those do not have returns. That's the distinction between them (in languages that have them both)
 
  • #5
33,271
4,975
I thought that there must be an invisible "return 0;" there. Does the returned integer have to be zero? What if it isn't? I just wrote a simple program without writing return at the end and it says that the "Process exited after 2.16 seconds with return value 10."
You could have main() return some other integer value that could be used by a batch file that is calling your program.

As far as how return works, if your program is running on an x86 processor, there is code that places the return value in the EAX register. Other functions that return integral values (but not floating point values) do the same.
 
  • #6
rcgldr
Homework Helper
8,680
514
In the case of MSDOS or Windows, mains return value is an "error code", which can be used in a batch file like "if %errorlevel% == 0 ...". In MSDOS, the exit value is returned in AL, so they are restricted to 0 through 255. I think Windows also restricts the values to 0 through 255 (probably masks the return value with 0xFF). Although it's called an error level, it could be used as a more generic way to control conditional code in batch files.
 
  • #7
Ibix
Science Advisor
Insights Author
5,961
4,531
Although it's called an error level, it could be used as a more generic way to control conditional code in batch files.
Many things do use it as an error code, though. I used to have my Linux command prompt set up so the prompt was normally green text, but switched to red text if the last command returned non-zero.
 
  • #8
1,516
617
Many things do use it as an error code, though. I used to have my Linux command prompt set up so the prompt was normally green text, but switched to red text if the last command returned non-zero.
Same. This is the response code of the program, which is very very useful.

As to why you don't need it sometimes, C compilers are allowed to do things beyond what the standard says. The C Standard (C11) specifies that these two MUST be valid:
int main(void);
int main(int argc, char* argv[]);
But compilers are free to make additional mains if they want. I'm certain that all major ones GCC and VisualC support void and have an implicit return 0.
 
  • #9
wle
307
136
My understanding is that if the main function's return type is an integer, i.e. it looks like this: int main () {...}, then "return 0;" must be written otherwise the function won't work.
No. In C since the 1999 standard, if you reach the end of the main function and there's no return statement then the behaviour is the same as if you did "return 0;":
5.1.2.2.3 Program termination

If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.
In the earlier 1989 standard, omitting the return statement returns an undefined value:
"Program termination"

A return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument. If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined.
Either way it's still considered good style to put an explicit return statement at the end of your main() function, even if you don't technically have to.


My professor said that the exception would be if you wrote "void" in the parenthesis like this: "int main (void)".
No, this is something different. In C, "int main(void)" means that the main function takes no arguments. "int main()" without the "void" means that main takes an unspecified number of arguments. You can see the difference if you call main yourself. For example, this is bad but valid C code and should compile without any error:
C:
int main()
{
    main(3.14159, "hello", 42);
    return 0;
}
But you will get an error if you use void.

Note that C++ is different from C here. "int main()" and "int main(void)" in C++ both mean the same thing as "int main(void)" in C.

Basically, if you're writing a main function that takes no arguments then you should use "int main(void)" if you're writing C code and "int main()" if you're writing C++ code.
 
Last edited:
  • #10
1,516
617
"int main()" without the "void" means that main takes an unspecified number of arguments.
Is this a specific weird quirk of main? Because in every other function in C, an empty set of parenthesis is exactly equivalent to (void). The way you have a variable set of parameters is with the ellipsis: printf(const char *, ...)
 
  • #11
wle
307
136
Is this a specific weird quirk of main?
No, it's the same for any other function. This seems to be a relic of old C before the ANSI standard, which used a different syntax for function declarations and apparently didn't yet support argument lists and types in function prototypes. See point #3 here: http://ee.hawaii.edu/~tep/EE160/Book/chapapx/node7.html.
 
  • #12
25
1
What compiler are you using?
I'm using Dev C++. Check this out.
Code:
#include <stdio.h>
int main () {
    int x;
    x = 0; 
    while(x <= 10) {
        if (x%2==0) {
            printf("%d ", x); 
            printf("%d ", x);
        }
        else printf("%d ", x); 
        x = x+1; 
    }
}
Here's some code I wrote for homework. Notice that there isn't a "return 0;" at the end. If you run the code on Dev C++, this happens.
Capture.PNG

Why is the return value three?
No, this is something different. In C, "int main(void)" means that the main function takes no arguments. "int main()" without the "void" means that main takes an unspecified number of arguments. You can see the difference if you call main yourself. For example, this is bad but valid C code and should compile without any error:
What does it mean that the function "takes no arguments?" What are arguments?
 

Attachments

  • #13
33,271
4,975
I'm using Dev C++. Check this out.
Code:
#include <stdio.h>
int main () {
    int x;
    x = 0;
    while(x <= 10) {
        if (x%2==0) {
            printf("%d ", x);
            printf("%d ", x);
        }
        else printf("%d ", x);
        x = x+1;
    }
}
Here's some code I wrote for homework. Notice that there isn't a "return 0;" at the end. If you run the code on Dev C++, this happens.
View attachment 227960
Why is the return value three?
That's the value that happened to be in the AX register when main() exited. If you had included "return 0;" in your code, that's the value that would have been returned.
dect117 said:
What does it mean that the function "takes no arguments?" What are arguments?
As you declared main(), with empty pair of parentheses, that says that your main() has no parameters. main() can be declared in other ways, with a parameter list, one of which is the way @newjerseyrunner has it in post #8.
int main(int argc, char* argv[]);
In this declaration, main() has two parameters: argc and argv, which are useful if you want to call your program from a batch file, and pass a string of arguments to it.
 
  • #14
25
1
As you declared main(), with empty pair of parentheses, that says that your main() has no parameters. main() can be declared in other ways, with a parameter list, one of which is the way @newjerseyrunner has it in post #8.
Okay, but why is it ever necessary to put "void" in between the parenthesis? I understand that this signifies that the main function doesn't take any arguments. I'm just confused as to what that means exactly.
 
  • #15
.Scott
Homework Helper
2,455
851
Is this a specific weird quirk of main? Because in every other function in C, an empty set of parenthesis is exactly equivalent to (void). The way you have a variable set of parameters is with the ellipsis: printf(const char *, ...)
Yes, the C standards specify different handling for the main function than for other functions:
https://en.cppreference.com/w/cpp/language/return
If control reaches the end of the main function, return 0; is executed.
Flowing off the end of a value-returning function (except main) without a return statement is undefined behavior.
In a function returning void, the return statement with expression can be used, if the expression type is void.
 
  • #16
.Scott
Homework Helper
2,455
851
I'm using Dev C++. Check this out.
Code:
#include <stdio.h>
int main () {
    int x;
    x = 0;
    while(x <= 10) {
        if (x%2==0) {
            printf("%d ", x);
            printf("%d ", x);
        }
        else printf("%d ", x);
        x = x+1;
    }
}
Here's some code I wrote for homework. Notice that there isn't a "return 0;" at the end. If you run the code on Dev C++, this happens.
...
Why is the return value three?
As mentioned in my previous post, the C standard specifies that running to the end of a main function will result in a "return 0". Since per the C specifications, your code is a valid main function, this function should return 0. The fact that it does not means that your compiler does not comply with the standard.

Instead, your compiler seems to have treated this as a regular routine and left the return value unspecified. As @Mark44 noted, on Intel machines, C is normally implemented by returning integer values through the AX register. By not setting the AX register to a specific return value, it was left at whatever value is had from its last use - probably related to the printf statements.

What does it mean that the function "takes no arguments?" What are arguments?
They are the list of parameters pass to a function withing the parenthesis.
 
  • #17
wle
307
136
I'm using Dev C++. Check this out.
Code:
#include <stdio.h>
int main () {
    int x;
    x = 0;
    while(x <= 10) {
        if (x%2==0) {
            printf("%d ", x);
            printf("%d ", x);
        }
        else printf("%d ", x);
        x = x+1;
    }
}
Here's some code I wrote for homework. Notice that there isn't a "return 0;" at the end. If you run the code on Dev C++, this happens.
View attachment 227960
Why is the return value three?
Well are you using C or C++? There are many subtle differences between them and there are different versions of both C and C++. For example, historically there have been at least four different versions of the C language:
  • The original C, described in the first edition of The C Programming Language by Kernighan and Ritchie, published in 1978.
  • ANSI C or C89, defined by the 1989 ANSI standard.
  • C99, defined by the later 1999 ANSI standard.
  • C11, defined by the 2011 ANSI standard.
C++ and versions of C starting with the C99 standard follow the "implicit return 0;" rule at the end of the main function. The older C89 version of C doesn't. So you could have got the result you did if Dev C++ compiled your code using a C compiler and it was conforming to the C89 standard.


Okay, but why is it ever necessary to put "void" in between the parenthesis?
This is another case where it is important to know if you are writing C or C++. You need to put "void" between the parentheses to say that main doesn't take any arguments only if you're writing C code. If you're writing C++ code you don't need "void".


I understand that this signifies that the main function doesn't take any arguments. I'm just confused as to what that means exactly.
The main function is a function that can be called, possibly with arguments if it accepts them, just like any other function in C.

For example, you called another function printf in your code when you wrote printf("%d ", x);. In that case, the printf function is accepting two arguments: the string "%d " and the value of the variable x. Since main is a function, you can call it yourself at any point in your code (although it is unusual that you would want to do this). If you declare that main doesn't take arguments then it is illegal to call it with parameters, e.g. you can call it with main() but not something like main(3.14159, "hello", 42).

Have you learned about functions yet? If not then don't worry about it too much yet. You'll understand this better when you learn about functions and function arguments.
 
  • #18
326
32
If I want to return a value from main(), as in a compiled program, I use the exit(int) function.
 

Related Threads on How does "return 0;" work and why is it necessary?

Replies
1
Views
1K
  • Last Post
Replies
15
Views
976
Replies
2
Views
3K
Replies
15
Views
1K
  • Last Post
Replies
6
Views
2K
  • Last Post
Replies
1
Views
1K
  • Last Post
Replies
6
Views
605
  • Last Post
Replies
9
Views
2K
  • Last Post
Replies
6
Views
2K
Top