Question
In C and C++, what is the correct and standard way to define the main() function: int main() or void main()? Why is one preferred over the other?
Also, what arguments can main() legally accept, and what do they represent?
If main() returns int, should a program return 0 or 1, and what do those values mean?
Example forms often discussed are:
int main(void)
{
return 0;
}
int main(int argc, char *argv[])
{
return 0;
}
void main()
{
}
Which forms are correct in C and C++, and which should be avoided?
Short Answer
By the end of this page, you will understand the standard return type of main() in C and C++, which argument forms are valid, what exit codes mean, and why void main() should be avoided in portable programs.
Concept
In both C and C++, main() is the program's entry point. It is special: the language standards define how it should look and what its return value means.
The key rule is:
main()should returnintvoid main()is not standard in either C or C++
Why int?
Because when your program finishes, it returns a status code to the operating system. That status code tells the system whether the program succeeded or failed.
0usually means success- nonzero usually means some kind of error or abnormal situation
This matters in real programming because other programs, shell scripts, build tools, test runners, and operating systems often check a program's exit status.
For example:
- a build script may stop if your program returns a nonzero value
- a CI pipeline may mark a step as failed
- a shell script may run different logic depending on the result
In standard C, the common valid forms are:
int main(void)
int main(int argc, char *argv[])
In standard C++, the common valid forms are:
int main()
int main(int argc, char* argv[])
You may also see equivalent forms of the argument list, such as:
int main(int argc, char **argv)
These are equivalent for practical use.
Another important rule: if control reaches the end of main() in C++ or in modern C, it is treated as if return 0; were written. Still, many developers write return 0; explicitly for clarity, especially in beginner code.
So the short answer is:
- Use
int main(...) - Return
0for success - Return a nonzero value for failure or special error states
- Avoid
void main()if you want standard, portable code
Mental Model
Think of main() like the front desk of a building.
- The operating system sends your program in through the front door.
main()is the receptionist that handles the visit.- When the program finishes, the receptionist sends back a small status note.
That note is the integer return value.
0means: "Everything went fine."1or another nonzero value means: "Something went wrong" or "I finished with a warning/error state."
If main() were void, it would be like leaving the building without giving any status note back. Some compilers may allow it, but the official rules of C and C++ expect that note to be an integer.
Syntax and Examples
Standard forms
C
int main(void)
{
return 0;
}
int main(int argc, char *argv[])
{
return 0;
}
C++
int main()
{
return 0;
}
int main(int argc, char* argv[])
{
return 0;
}
What the arguments mean
argc= argument countargv= argument vector, an array of C-style strings
If you run a program like this:
./app hello world
then typically:
argcis3argv[0]is"./app"argv[1]is"hello"argv[2]is"world"
Example: printing command-line arguments in C
#include <stdio.h>
int main(int argc, char *argv[])
{
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
This program prints every argument passed on the command line.
Example: returning an error code
#include <stdio.h>
int main(void)
{
int configLoaded = 0;
if (!configLoaded) {
printf("Failed to load configuration.\n");
return 1;
}
return 0;
}
Here:
return 1;signals failurereturn 0;signals success
Form to avoid
void main()
{
}
This may compile on some systems, but it is not the standard definition of main() in C or C++. Avoid it in portable code.
Step by Step Execution
Consider this example:
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Usage: program <name>\n");
return 1;
}
printf("Hello, %s!\n", argv[1]);
return 0;
}
Step by step:
- The operating system starts the program and calls
main. - It passes in:
argc, the number of command-line argumentsargv, the array of argument strings
- The program checks
if (argc < 2).- If true, the user did not provide the required extra argument.
- If the argument is missing, the program prints a usage message.
- It then executes
return 1;.- This tells the operating system that the program did not complete successfully.
- If the user did provide an argument, the condition is false.
- The program prints
Hello, ...usingargv[1]. - It executes
return 0;.- This tells the operating system the run was successful.
Example runs:
./program
Output:
Usage: program <name>
Exit status: nonzero
./program Alice
Output:
Hello, Alice!
Exit status: 0
Real World Use Cases
Programs use main() return values constantly in real systems.
Command-line tools
A CLI tool may return:
0when the command succeeded1when input was invalid- another nonzero code for a specific failure
Build and automation scripts
Tools like shell scripts, Makefiles, and CI jobs often check exit codes.
Example idea:
- compile program
- run test executable
- if the test executable returns nonzero, fail the build
Server startup checks
A server process may return nonzero if:
- configuration file is missing
- database connection fails
- required port cannot be opened
Data processing programs
A batch job may return:
0if all files were processed- nonzero if one or more files failed
Educational and debugging tools
Programs that expect command-line arguments use argc and argv to read:
- file names
- modes like
--verbose - user input values
Real Codebase Usage
In real codebases, developers usually treat main() as a small coordinator function.
Common patterns include:
Guard clauses for startup validation
int main(int argc, char *argv[])
{
if (argc < 2) {
return 1;
}
return 0;
}
This is called an early return or guard clause. It exits quickly if startup conditions are not met.
Returning meaningful status codes
int main(void)
{
if (!init_system()) {
return 2;
}
if (!run_job()) {
return 3;
}
return 0;
}
Different nonzero values can help scripts or developers identify the failure stage.
Delegating work to helper functions
main() is often kept short:
int run_app(int argc, char *argv[])
{
return 0;
}
int main(int argc, char *argv[])
{
return run_app(argc, argv);
}
This makes testing and maintenance easier.
Argument parsing
Developers often use argc and argv to parse flags and options.
int main(int argc, char *argv[])
{
if (argc > 1 && argv[1][0] == '-') {
/* handle option */
}
return 0;
}
Error reporting plus exit code
A common pattern is:
- print an error message to the user
- return nonzero
That gives both human-readable output and machine-readable status.
Common Mistakes
Using void main()
Broken example:
void main()
{
printf("Hello\n");
}
Why it is a mistake:
- it is not standard C or C++
- it may work only on some compilers
- it does not correctly express an exit status
Use this instead:
int main(void)
{
printf("Hello\n");
return 0;
}
Returning 1 for success
Broken example:
int main(void)
{
return 1;
}
Why it is a mistake:
- by convention and standard practice,
0means success - nonzero indicates failure or a special abnormal result
Use:
return 0;
for success.
Forgetting what argc contains
Broken assumption:
- beginners often think
argccounts only the extra arguments
But argc usually includes the program name as argv[0].
So if the program needs one user argument, usually check:
if (argc < 2)
not:
if (argc < 1)
Accessing argv[1] without checking
Broken example:
int main(int argc, char *argv[])
{
printf("%s\n", argv[1]);
return 0;
}
Why it is a mistake:
- if no argument was passed,
argv[1]is invalid to use
Safer version:
int main(int argc, char *argv[])
{
if (argc < 2) {
return 1;
}
printf("%s\n", argv[1]);
return 0;
}
Assuming compiler-specific behavior is portable
Some compilers accept nonstandard forms of main(). That does not make them correct for portable C or C++ code. Prefer the standard forms.
Comparisons
| Form | C | C++ | Portable | Notes |
|---|---|---|---|---|
int main(void) | Yes | Not typical style, but conceptually no-arg | Yes in C, not the usual C++ form | Standard no-argument form in C |
int main() | Old-style declaration issue in C, avoid in modern C | Yes | Best for C++ | Standard no-argument form in C++ |
int main(int argc, char *argv[]) | Yes | Yes | Yes | Standard argument-taking form |
int main(int argc, char **argv) | Yes | Yes | Yes | Equivalent to char *argv[] |
void main() | No | No | No | Nonstandard; avoid |
return 0 vs return 1
| Return value | Meaning |
|---|---|
0 | Success |
nonzero such as 1 | Error, failure, or special status |
C vs C++ no-argument style
| Language | Preferred no-argument form |
|---|---|
| C | int main(void) |
| C++ | int main() |
The reason for this difference is that in C, void explicitly means no parameters, while in C++ int main() already means no parameters.
Cheat Sheet
Correct forms
C
int main(void)
int main(int argc, char *argv[])
C++
int main()
int main(int argc, char* argv[])
Avoid
void main()
Return values
return 0;→ successreturn 1;or other nonzero value → failure or special error status
Arguments
argc= number of argumentsargv= array of stringsargv[0]is usually the program name/path
Equivalent argument syntax
int main(int argc, char *argv[])
int main(int argc, char **argv)
Practical rule
- C: prefer
int main(void)when there are no arguments - C++: prefer
int main()when there are no arguments - use the
argc/argvform when reading command-line input
Edge notes
- Falling off the end of
main()is treated likereturn 0;in C++ and modern C - explicit
return 0;is still often written for clarity - standard portable code should not use
void main()
FAQ
Is void main() ever correct in C or C++?
No, not in standard C or standard C++. Some compilers may accept it as an extension, but portable code should not use it.
Should main() always return 0?
No. It should return 0 on success and a nonzero value when the program fails or wants to report a special status.
What does argc mean?
argc is the number of command-line arguments passed to the program, usually including the program name.
What is argv in main()?
argv is an array of C-style strings containing the command-line arguments.
Is int main() valid in C?
In C++, yes. In C, the preferred no-argument form is int main(void) because it explicitly states there are no parameters.
What is the difference between char *argv[] and char **argv?
For this use, they are equivalent ways to declare the argument list.
What should I return if an input file is missing?
Return a nonzero value, such as 1, after optionally printing an error message.
Can I omit return 0; at the end of main()?
Yes, in C++ and modern C it is treated as success. Many programmers still write it explicitly for readability.
Mini Project
Description
Build a small command-line program that greets a user by name and returns a meaningful exit status. This demonstrates the correct main() signature, safe use of argc and argv, and proper success/failure return values.
Goal
Create a program that accepts one command-line argument, prints a greeting when the input is present, and returns a nonzero status when it is missing.
Requirements
- Define
main()using a standardintreturn type. - Accept command-line arguments with
argcandargv. - If no name is provided, print a usage message and return a nonzero value.
- If a name is provided, print
Hello, <name>!and return0.
Keep learning
Related questions
2D Array Loop Order and Cache Performance in C
Learn why swapping nested loops changes 2D array performance in C, using row-major memory layout, cache locality, and practical benchmarks.
Array-to-Pointer Conversion in C and C++ Explained
Learn what array-to-pointer conversion means in C and C++, how array decay works, and how it differs from a pointer to an array.
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.