Question

What main() Should Return in C and C++

ccppreturn-valueprogram-entry-pointreturn-type

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 return int
  • void 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.

  • 0 usually 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 0 for 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.

  • 0 means: "Everything went fine."
  • 1 or 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.

Take Quiz

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 count
  • argv = argument vector, an array of C-style strings

If you run a program like this:

./app hello world

then typically:

  • argc is 3
  • argv[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 failure
  • return 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:

  1. The operating system starts the program and calls main.
  2. It passes in:
    • argc, the number of command-line arguments
    • argv, the array of argument strings
  3. The program checks if (argc < 2).
    • If true, the user did not provide the required extra argument.
  4. If the argument is missing, the program prints a usage message.
  5. It then executes return 1;.
    • This tells the operating system that the program did not complete successfully.
  6. If the user did provide an argument, the condition is false.
  7. The program prints Hello, ... using argv[1].
  8. 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:

  • 0 when the command succeeded
  • 1 when 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:

  • 0 if 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
Take Quiz

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, 0 means success
  • nonzero indicates failure or a special abnormal result

Use:

return 0;

for success.

Forgetting what argc contains

Broken assumption:

  • beginners often think argc counts 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

FormCC++PortableNotes
int main(void)YesNot typical style, but conceptually no-argYes in C, not the usual C++ formStandard no-argument form in C
int main()Old-style declaration issue in C, avoid in modern CYesBest for C++Standard no-argument form in C++
int main(int argc, char *argv[])YesYesYesStandard argument-taking form
int main(int argc, char **argv)YesYesYesEquivalent to char *argv[]
void main()NoNoNoNonstandard; avoid

return 0 vs return 1

Return valueMeaning
0Success
nonzero such as 1Error, failure, or special status

C vs C++ no-argument style

LanguagePreferred no-argument form
Cint 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.

Take Quiz

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; → success
  • return 1; or other nonzero value → failure or special error status

Arguments

  • argc = number of arguments
  • argv = array of strings
  • argv[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/argv form when reading command-line input

Edge notes

  • Falling off the end of main() is treated like return 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.

Take Quiz

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 standard int return type.
  • Accept command-line arguments with argc and argv.
  • If no name is provided, print a usage message and return a nonzero value.
  • If a name is provided, print Hello, <name>! and return 0.
Take Quiz

Keep learning

Related questions

View more