Skip to content

Instantly share code, notes, and snippets.

@eisenwave
Created July 22, 2025 09:58
Show Gist options
  • Select an option

  • Save eisenwave/78d6127b73c6c9a1bc4cb55ad7bf249c to your computer and use it in GitHub Desktop.

Select an option

Save eisenwave/78d6127b73c6c9a1bc4cb55ad7bf249c to your computer and use it in GitHub Desktop.
D3803R0 More standard forms of main

More standard forms of main

Introduction

As explained in [basic.start.main] paragraph 2, there are only two function types for main which an implementation is required to support:

  • int()
  • int(int, char**)

In practice, every major compiler supports additional forms. This proposal seeks to standardize existing practice by requiring that the following types are also supported:

  • int(int, const char**),
  • int(int, char*const*),
  • int(int, const char*const*), and
  • any of the supported types, with noexcept.

Motivation

One of the most important tasks of WG21 is to standardize existing practice. A search for uses of const qualifications in the argv pointer (const-main) reveals 225K C++ files. It is silly that many thousands of int main(int, const char**) functions are technically non-standard code, as most C++ users either don't know or don't care about this technicality.

Furthermore, a search for uses of noexcept on main (noexcept-main) reveals roughly 1K C++ files. This seems like a reasonable feature to support, as noexcept can be used to express that no exceptions can reach main. It can also express that an exception may reach main and std::terminate is called ([except.terminate]). std::terminate would be called if an exception "escaped" main anyway, but some users may find it more expressive to document this explicitly.

Design

The goal of this proposal is merely to align the standard with existing practice, at minimal or no cost to implementations.

Therefore, I do not propose any substantial change to how program arguments are passed to main, such as permittng the use of std::string_view[] as argv. I also do not propose const volatile** argv because there is very little motivation for that, and support for volatile in argv is not as ubiqutous.

Feature testing

If a user really wanted to write code without assuming that these new forms of main are supported (which seems unlikely), they could do so as follows:

int main2(int argc, const char * const * argv) noexcept {
    // ...
}

int main(int argc, char** argv) { return main2(argc, argv); }

Therefore, feature-test macros feel unmotivated.

Unicode support

Supporting Unicode forms of main such as with a char8_t** argv parameter are outside the scope of this proposal. As stated, the goal is to standardize existng practice. If implementations wanted to provide support for char8_t** argv, they could already do so, as additional non-standard forms of main are permitted. However, no implementation supports Unicode argv.

[P3474R0] already provides std::arguments as a way to obtain transcoded program arguments. In general, a library solution to this problem may be less of a burden than requiring Unicode argv.

void main()

At the time of writing, MSVC accepts void main() without warnings, EDG accepts void main() with warnings, and GCC and Clang reject this declaration. Support for void main() is currently not proposed, but should be considered by EWG.

The main argument in favor of permitting a void return type is that it makes main substantially less "magical". main is the only non-void function where omitting a return statement is well-defined. C++ teachers in beginner courses have the choice of explaining

  • what return 0 is supposed to mean, or
  • why a missing return statement in main is okay, despite the return type being int.

Neither option is compelling.

However, it could also be argued that bifurcating the language by having some users write int main and other users write void main is making the situation more complicated and harder to teach, undoing any benefits.

DECISION REQUIRED

Impact on implementations

GCC, Clang, MSVC, and EDG all support the proposed forms of main which add const to argv, with no errors or warnings. All but EDG also support noexcept on main.

Therefore, implementing this proposal is almost a no-op for major implementations.

Impact on existing code

Some non-standard code would be elevated to standard code. No other impact.

Wording

Change [basic.start.main] paragraph 2 as follows:

An implementation shall not predefine the main function. Its type shall have C++ language linkage and it shall have a declared return type of type int, but otherwise its type is implementation-defined. An implementation shall allow both
  • a noexceptopt function of () returning int
  • a noexceptopt function of (int, constopt pointer to constopt pointer to char) returning int

as the type of main([dcl.fct]). [...]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment