Language[lang]

C++ main function: int main(), argc and argv

Section
Language [lang]
Standard
C++17
Compilers
MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
Published
Length
8 min read
In this answer8 clauses
  1. 1What are the two forms of main?
  2. 2Why does main return int?
  3. 3Do you need return 0 in main?
  4. 4How do you read command-line arguments with argc and argv?
  5. 4.1How do you convert an argument to a number?
  6. 5Can main be void?
  7. 6What can’t you do with main?
  8. 7What runs before and after main?
  9. 8The forms of main at a glance

Abstract

The C++ main function is where your program starts, and it must return int: write int main(), or int main(int argc, char* argv[]) to read command-line arguments. The value main returns is the exit status, where 0 or EXIT_SUCCESS means success, and reaching the end of main without a return is the same as return 0. void main() is not standard C++.

A frame, the program, holds four blocks of code drawn as bars. An arrow from a command prompt enters the blue block, main, which calls the other three; a second arrow returns to the prompt.
Figure 1 — Every program has one way in: whatever starts the program calls main, and when main returns, the program ends.

The C++ main function is where your program starts: when you run the program, the system calls main, and when main returns, the program ends. It must return int, and it has two standard forms, int main() and int main(int argc, char* argv[]), the second for reading command-line arguments. Returning 0 reports success.

The smallest whole program:

[Example 1:
#include <iostream>

int main() {
    std::cout << "Hello from main!\n";
    return 0;  // 0: the program succeeded
}

— end example]

It printed Hello from main! and ended with exit status 0. The samples on this page are C++17, built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++), and all four did the same unless a section says otherwise. Since When lists the compiler releases that support each standard.

What are the two forms of main?

Standard C++ gives main two forms: int main() for a program that takes no arguments, and int main(int argc, char* argv[]) for one that reads its command line ([basic.start.main]). int main(int argc, char** argv) is the second form spelled another way: both declare argv as a pointer to pointer to char. A compiler may accept more forms, such as extra parameters after argv, but those are its own; the two standard forms work on every compiler.

Why does main return int?

The number main returns is the program’s exit status: it goes back to whatever started the program, such as a shell or a build script, which can test it. Return 0 or EXIT_SUCCESS for success and EXIT_FAILURE for failure; both names come from <cstdlib> (EXIT_SUCCESS and EXIT_FAILURE on cppreference). The running example is greet, a program that says hello to a name. It fails when it gets none:

[Example 2:
#include <cstdlib>
#include <iostream>

int main(int argc, char* argv[]) {
    if (argc < 2) {  // no name given
        std::cerr << "usage: greet NAME\n";
        return EXIT_FAILURE;  // the check failed
    }
    std::cout << "Hello, " << argv[1] << "!\n";
    return EXIT_SUCCESS;  // the same as return 0
}

— end example]

Started with no name, it printed usage: greet NAME to std::cerr, the error stream, and ended with exit status 1, the value EXIT_FAILURE had in every build, on Windows and on Linux. Bash and other POSIX shells give it as $?, PowerShell as $LASTEXITCODE, the Windows command prompt as %ERRORLEVEL%.

Do you need return 0 in main?

No. When main reaches its closing brace without a return, the effect is the same as return 0;, so this program also reports success:

[Example 3:
#include <iostream>

int main() {
    std::cout << "Hello from main!\n";
}  // no return: the same as return 0

— end example]

It exited with status 0 on all four. The rule covers main alone: every other function that promises a value must return one (how C++ functions return values).

How do you read command-line arguments with argc and argv?

argc counts the arguments, the program’s name included, and argv holds them as C strings, character arrays that end in '\0'. For the command line greet Ana 3, argc is 3, argv[0] is the name the program was started with, argv[1] is Ana, argv[2] is 3, and argv[argc] is a null pointer:

The command line greet Ana 3, then argc, a box holding 3, and argv, a row of four slots: argv 0, 1 and 2 point to the strings greet, Ana and 3; argv 3 is crossed out: a null pointer.
Figure 2 — argc counts the arguments, the program's name included; argv holds them as C strings and ends with a null pointer.

The standard promises less than the picture shows: argc is not negative, argv[argc] is a null pointer, and argv[0], when there is one, is the name used to start the program or an empty string (main function on cppreference). So check argc before you read argv[1].

This sample prints what it receives. Its work is in run, which takes main’s two parameters; main passes it the array that greet Ana 3 produces, written out by hand, and then its own argc and argv:

[Example 4:
int run(int argc, char* argv[]) {
    std::cout << "argc: " << argc << '\n';
    if (argc > 0) {  // argv[0]: the program's name, or ""
        std::cout << "argv[0] is "
                  << (argv[0][0] != '\0' ? "not empty" : "empty")
                  << '\n';
    }
    for (int i = 1; i < argc; ++i) {
        std::cout << "argv[" << i << "]: " << argv[i] << '\n';
    }
    std::cout << "argv[argc] is "
              << (argv[argc] == nullptr ? "a null pointer" : "set")
              << '\n';
    return 0;
}

int main(int argc, char* argv[]) {
    // what main would get from the command line: greet Ana 3
    char greet[] = "greet";
    char ana[] = "Ana";
    char three[] = "3";
    char* args[] = {greet, ana, three, nullptr};
    std::cout << "-- greet Ana 3 --\n";
    run(3, args);
    // ...
    return run(argc, argv);
}

— end example]

For greet Ana 3 it printed:

[Example 5:
-- greet Ana 3 --
argc: 3
argv[0] is not empty
argv[1]: Ana
argv[2]: 3
argv[argc] is a null pointer

— end example]

Started with no arguments, argc was 1 on all four, for the program’s name, and argv[1] was the null pointer that ends the list.

How do you convert an argument to a number?

Every argument arrives as text, so a number has to be converted, and the conversion can fail. std::stoi, from <string>, returns the int or throws an exception: std::invalid_argument for text such as three, std::out_of_range for a number that does not fit in an int. The greet program checks argc, then reads its repeat count inside try and catch:

[Example 6:
int run(int argc, char* argv[]) {
    if (argc < 3) {  // check argc before reading argv[2]
        std::cerr << "usage: greet NAME COUNT\n";
        return EXIT_FAILURE;
    }
    int count = 0;
    try {
        count = std::stoi(argv[2]);
    } catch (const std::invalid_argument&) {
        std::cerr << "COUNT is not a number: " << argv[2] << '\n';
        return EXIT_FAILURE;
    } catch (const std::out_of_range&) {
        std::cerr << "COUNT is too large: " << argv[2] << '\n';
        return EXIT_FAILURE;
    }
    for (int i = 0; i < count; ++i) {
        std::cout << "Hello, " << argv[1] << "!\n";
    }
    return EXIT_SUCCESS;
}

— end example]

For greet Ana 3 it printed Hello, Ana! three times and returned EXIT_SUCCESS. For greet Ana three it printed COUNT is not a number: three and returned EXIT_FAILURE, and for greet Ana 99999999999, COUNT is too large: 99999999999. std::stoi also stops quietly at the first character that is not part of the number: std::stoi("3x") returned 3 on all four, so greet Ana 3x greets three times. Converting a string to an int shows how to reject trailing text and compares std::stoi with std::from_chars.

Can main be void?

No. Standard C++ requires main to return int, so void main() is not C++. GCC and Clang reject it with an error (Clang: 'main' must return 'int'); MSVC compiles it with warning C4326 and the program runs, because Microsoft accepts void main as an extension it does not recommend (Microsoft’s page on main). Such a main has no exit status to return: write int main().

What can’t you do with main?

main follows rules no other function has. You may not:

  • call it or take its address: the standard says main “shall not be named by an expression”. Put work that repeats in another function and call that from main.
  • overload it: a second main with other parameters was an error on all four (MSVC: 'main': function cannot be overloaded).
  • declare it inline, static or constexpr.
  • write auto main() and let the compiler deduce the return type.

The first rule is the one compilers enforce least: a function that calls main compiled on all four without a warning at /W4 and -Wall -Wextra, and GCC and Clang warned only with -pedantic.

What runs before and after main?

Global objects are normally constructed before main’s first statement and destroyed after main returns, in the reverse order of construction. The “normally” is there because the standard leaves it to the implementation: it may defer a global’s initialization, as long as it runs before the first use of a function or variable defined in the same translation unit, the source file plus the headers it includes ([basic.start.dynamic]). So main is where your code starts, but not always the first code to run:

[Example 7:
#include <iostream>

struct Banner {
    Banner() { std::cout << "Banner constructed\n"; }
    ~Banner() { std::cout << "Banner destroyed\n"; }
};

Banner banner;  // a global object

int main() {
    std::cout << "main starts\n";
    std::cout << "main ends\n";
}

— end example]

It printed, on all four:

[Example 8:
Banner constructed
main starts
main ends
Banner destroyed

— end example]

Returning from main works like calling std::exit with the returned value, and std::exit destroys the global objects ([basic.start.term]).

The forms of main at a glance

Form Standard C++? Use it when
int main() yes the program takes no arguments
int main(int argc, char* argv[]) yes the program reads its command line
int main(int argc, char** argv) yes, the same form you prefer this spelling of argv
void main() no: GCC and Clang reject it never: write int main()
int main(int argc, char* argv[], char* envp[]) no: an extension some systems have rarely: std::getenv reads a variable in standard C++

More answers on the core language are in the Language section.

Questions

What does return 0 mean in C++?

In main, return 0 ends the program and reports success to whatever started it, such as a shell or a script. The number is the program’s exit status: 0 and EXIT_SUCCESS mean success, EXIT_FAILURE means failure. Leaving it out of main changes nothing, because reaching the end of main is the same as return 0.

What is the difference between int main() and int main(void)?

None in C++: both declare a main that takes no arguments. (void) is the C spelling of an empty parameter list; in C++ the empty parentheses of int main() already say it.

What is argv[0] in C++?

argv[0] is the name the program was started with, or an empty string: the standard allows either. Microsoft notes that on Windows it is the program’s file name by convention, but a program that starts yours with CreateProcess can make it something else. If argc is 0, which the standard also allows, argv[0] is the null pointer that ends the list.

Can main call itself in C++?

No. The standard says main shall not be named by an expression, so no function may call it, main included. MSVC, GCC and Clang compiled a call to main without a warning at /W4 and -Wall -Wextra (GCC and Clang warn only with -pedantic), so put the repeating work in another function and call that from main.

Can a C++ program have two main functions?

No: a program has exactly one main in the global namespace. Two source files that each define one failed to link on MSVC, GCC and Clang (MSVC: LNK2005, main already defined), and a second main with a different parameter list in the same file did not compile. A function named main inside a namespace or a class is allowed: it is an ordinary function, not where the program starts.

Is main a keyword in C++?

No. main is the name of a function, not a keyword, but the standard gives that function rules no other function has: it must return int, and you may not call it, take its address or overload it.

Read next

  1. C++ functions: syntax, calling and overloadingLanguage · Miriam Castellanos · written for C++17
  2. constexpr in C++: variables, functions and static constexprLanguage · Miriam Castellanos · written for C++17
  3. Inheritance in C++: base and derived classesLanguage · Miriam Castellanos · written for C++17