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.
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.
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.
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.
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.
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 0is supposed to mean, or - why a missing
returnstatement inmainis okay, despite the return type beingint.
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
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.
Some non-standard code would be elevated to standard code. No other impact.
Change [basic.start.main] paragraph 2 as follows:
An implementation shall not predefine themainfunction. Its type shall have C++ language linkage and it shall have a declared return type of typeint, but otherwise its type is implementation-defined. An implementation shall allow both
- a
noexceptopt function of()returningint- a
noexceptopt function of(int,constopt pointer toconstopt pointer tochar)returningintas the type of
main([dcl.fct]). [...]