@@ -3420,82 +3420,120 @@ $(H2 $(LNAME2 main, The $(D main) Function))
34203420        It gets called after all the $(DDSUBLINK spec/module, staticorder, module initializers)
34213421        are run, and after any $(DDLINK spec/unittest, Unit Tests, unittests) are run.
34223422        After it returns, all the module destructors are run.
3423-         The $(D main) function typically is declared as follows:
34243423        )
34253424
3426- $(INFORMATIVE_GRAMMAR
3427- $(GNAME MainFunction):
3428-     $(GLINK MainReturnDecl) $(D main) $(LPAREN) $(RPAREN) $(GLINK FunctionBody)
3429-     $(GLINK MainReturnDecl) $(D main) $(LPAREN) $(D string) $(D [) $(D ]) $(GLINK_LEX Identifier)$(OPT) $(RPAREN) $(GLINK FunctionBody)
3430- 
3431- $(GNAME MainReturnDecl):
3432-     $(D void)
3433-     $(D int)
3434-     $(GLINK2 type, noreturn)
3435-     $(RELATIVE_LINK2 auto-functions, $(D auto))
3436-     $(GLINK_LEX Identifier)
3425+         $(P The `main` function must be named `main`. Other names are not possible,
3426+         not even using `pragma(mangle)` to change the mangling to the expected one.
3427+         )
34373428
3438- $(GNAME MainFunctionBody):
3439-     $(GLINK ShortenedFunctionBody)
3440-     $(GLINK SpecifiedFunctionBody)
3441- )
3429+         $(P The return type of `main` must be a possibly qualified version of `void`, `int`,
3430+         any `enum` type backed by `int`, or `noreturn`.
34423431
34433432        $(UL
34443433        $(LI If `main` returns `void`, the OS will receive a zero value on success.)
34453434        $(LI If `main` returns `void` or `noreturn`, the OS will receive a non-zero
34463435        value on abnormal termination, such as an uncaught exception.)
3436+         $(LI If `main` returns `int` or an `enum` type backed by `int`,
3437+         the OS will receive the returned value on success
3438+         and a non-zero value on abnormal termination.)
34473439        $(LI If `main` is declared as `auto`, the inferred return type must be
3448-         one of `void`, `int` and `noreturn`.)
3440+         one of the allowed types.)
3441+         )
3442+ 
3443+         $(P The `main` function must have either no parameters or a single parameter.
3444+         If provided, the parameter must be a possibly qualified version of `char[][]`,
3445+         and can optionally have the $(GLINK ParameterAttributes) `in`, `return` or `scope`.
3446+         It is customary to use `immutable(char)[][]`, i.e. `string[]`,
3447+         but, in particular `char[][]` is also allowed.
3448+         The argument passed to a `main` function with parameter is mutable and unique,
3449+         which is why it converts to `immutable`, `inout`, or `shared`.
34493450        )
34503451
34513452        $(P If the parameter is declared, it will hold
3452-         arguments passed to the program by the OS. The index-0 element is typically
3453+         arguments passed to the program by the operating system.
3454+         The index-0 element is typically
34533455        the executable name, followed by any command-line arguments.)
34543456
34553457        $(NOTE The runtime can remove any arguments prefixed `--DRT-`.)
34563458
3457-         $(NOTE The aforementioned return / parameter types may be annotated with $(D const) or
3458-         $(D immutable), or carry $(GLINK ParameterAttributes).
3459-         They may also be replaced by $(D enum) types with matching base types.)
3460- 
34613459        $(P The main function must have D linkage.)
34623460
34633461        $(P Attributes may be added as needed, e.g. `@safe`, `@nogc`, `nothrow`, etc.)
34643462
3463+         $(P The following grammar specification is an approximation of what is allowed for a D `main` function:)
3464+ 
3465+ $(INFORMATIVE_GRAMMAR
3466+ $(GNAME MainFunction):
3467+     $(GLINK2 declaration, StorageClasses)$(OPT) $(GLINK MainReturnType) main $(D $(LPAREN)) $(GLINK MainParameters)$(OPT) $(D $(RPAREN)) $(GLINK FunctionAttributes)$(OPT) $(GLINK MainFunctionBody)
3468+     $(GLINK2 declaration, StorageClasses) main $(D $(LPAREN)) $(GLINK MainParameters)$(OPT) $(D $(RPAREN)) $(GLINK FunctionAttributes)$(OPT) $(GLINK MainFunctionBody)
3469+ 
3470+ $(GNAME MainReturnType):
3471+     $(GLINK MainReturnBasicType)
3472+     $(GLINK2 type, TypeCtor) $(D $(LPAREN)) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK MainReturnBasicType) $(D $(RPAREN))
3473+ 
3474+ $(GNAME MainReturnBasicType):
3475+     $(D void)
3476+     $(D int)
3477+     $(GLINK_LEX Identifier)
3478+ 
3479+ $(GNAME MainParameters):
3480+     $(GLINK MainParameter)
3481+     $(GLINK MainParameter) $(D ,)
3482+ 
3483+ $(GNAME MainParameter):
3484+     $(GLINK MainParameterDeclaration)
3485+     $(GLINK MainParameterDeclaration) $(D =) $(GLINK2 expression, AssignExpression)
3486+ 
3487+ $(GNAME MainParameterDeclaration):
3488+     $(GLINK ParameterAttributes)$(OPT) $(GLINK MainParameterBasicType) $(GLINK MainParameterTypeSuffixes)$(OPT) $(GLINK_LEX Identifier)$(OPT)
3489+ 
3490+ $(GNAME MainParameterBasicType):
3491+     $(D char)
3492+     $(GLINK2 type, TypeCtor) $(D $(LPAREN)) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK MainParameterBasicType) $(GLINK MainParameterTypeSuffixes)$(OPT) $(D $(RPAREN))
3493+     $(GLINK_LEX Identifier)
3494+ 
3495+ $(GNAME MainParameterTypeSuffixes):
3496+     $(D [) $(D ])
3497+     $(D [) $(D ]) $(D [) $(D ])
3498+ 
3499+ $(GNAME MainFunctionBody):
3500+     $(GLINK SpecifiedFunctionBody)
3501+     $(GLINK ShortenedFunctionBody)
3502+ )
3503+ 
3504+     $(NOTE For $(GLINK MainReturnBasicType), the options of returning `noreturn` or an `enum` type are both covered by $(GLINK_LEX Identifier).)
3505+ 
34653506$(H2 $(LNAME2 betterc-main, $(D extern(C)) $(D main) Function))
34663507
3467-         $(P Programs may define an  $(D extern(C) main) function  as an alternative to the
3508+         $(P Programs may define a `main` function with  $(D extern(C)) linkage  as an alternative to the
34683509        standard $(RELATIVE_LINK2 main, entry point). This form is required for
34693510        $(DDLINK spec/betterc, Better C, $(B BetterC)) programs.)
34703511
3471-         $(P A C $(D  main)  function is typically declared  as follows:)
3512+         $(P A C ` main`  function differs from a D `main` function  as follows:)
34723513
3473- $(INFORMATIVE_GRAMMAR
3474- $(GNAME CMainFunction):
3475-     $(D extern) $(LPAREN) $(D C) $(RPAREN) $(GLINK MainReturnDecl) $(D main) $(LPAREN) $(GLINK CMainParameters)$(OPT) $(RPAREN) $(GLINK2 statement, BlockStatement)
3476- 
3477- $(GNAME CMainParameters):
3478-     $(D int) $(GLINK_LEX Identifier)$(OPT) $(D ,) $(D char**) $(GLINK_LEX Identifier)$(OPT)
3479-     $(D int) $(GLINK_LEX Identifier)$(OPT) $(D ,) $(D char**) $(GLINK_LEX Identifier)$(OPT) $(D ,) $(D char**) $(GLINK_LEX Identifier)$(OPT)
3480- )
3514+         $(UL
3515+         $(LI It has `extern(C)` linkage.)
3516+         $(LI If it has parameters, it has C `main` parameters instead of the D `main` parameter.)
3517+         $(LI No setup or teardown runs before or after a C `main` function.)
3518+         )
34813519
3482-         $(P When defined, the first two parameters denote a C-style array (length + pointer)
3483-         that holds the arguments passed to the program by the OS. The third parameter is a POSIX
3484-         extension called $(D environ) and holds information about the current environment variables.)
3520+         $(P All other rules for a D `main` function apply to C `main` functions.)
34853521
3486-         $(NOTE The exemption for storage classes / $(D enum)'s defined for a D $(D main) function
3487-         also applies to C $(D main) functions.)
3522+         $(P A C `main` function may have no parameters, two parameters, or three parameters.
3523+         When defined, the first two parameters denote a C-style array (length and pointer)
3524+         that holds the arguments passed to the program by the operating system. The third parameter, if present,
3525+         holds information about the current environment variables.)
34883526
3489-         $(P This function takes the place of the C  main function and  is executed immediately without
3490-         any setup or teardown associated with a D $(D  main)  function. Programs reliant on module
3491-         constructors, module destructors, or unittests need to manually perform (de)initialization
3527+         $(P A C ` main`  function is executed immediately without
3528+         any setup or teardown associated with a D ` main`  function. Programs reliant on module
3529+         constructors, module destructors, or unittests need to manually perform (de- )initialization
34923530        using the appropriate $(DDSUBLINK phobos/core_runtime, Runtime, runtime functions).)
34933531
34943532        $(IMPLEMENTATION_DEFINED Other system-specific entry points may exist, such as
34953533        `WinMain` and `DllMain` on Windows systems.
34963534        )
34973535
3498-         $(NOTE Programs targeting platforms which require a different signature for $(D  main)  can use
3536+         $(NOTE Programs targeting platforms which require a different signature for ` main`  can use
34993537        a function with $(DDSUBLINK spec/pragma, mangle, explicit mangling):
35003538
35013539        ---
@@ -3505,9 +3543,52 @@ $(GNAME CMainParameters):
35053543            return 0;
35063544        }
35073545        ---
3508- 
35093546        )
35103547
3548+         $(P The following grammar specification is an approximation of what is allowed for a C `main` function:)
3549+ 
3550+ $(INFORMATIVE_GRAMMAR
3551+ $(GNAME CMainFunction):
3552+     $(GLINK2 declaration, StorageClasses)$(OPT) $(GLINK MainReturnType) main $(D $(LPAREN)) $(GLINK CMainParameters)$(OPT) $(D $(RPAREN)) $(GLINK FunctionAttributes)$(OPT) $(GLINK MainFunctionBody)
3553+ 
3554+ $(GNAME CMainParameters):
3555+     $(GLINK CMainParameterList)
3556+     $(GLINK CMainParameterList) $(D ,)
3557+ 
3558+ $(GNAME CMainParameterList):
3559+     $(GLINK CMainFirstParameter) $(D ,) $(GLINK CMainNextParameter)
3560+     $(GLINK CMainFirstParameter) $(D ,) $(GLINK CMainNextParameter) $(D ,) $(GLINK CMainNextParameter)
3561+ 
3562+ $(GNAME CMainFirstParameter):
3563+     $(GLINK CMainFirstParameterDeclaration)
3564+     $(GLINK CMainFirstParameterDeclaration) $(D =) $(GLINK2 expression, AssignExpression)
3565+ 
3566+ $(GNAME CMainNextParameter):
3567+     $(GLINK CMainNextParameterDeclaration)
3568+     $(GLINK CMainNextParameterDeclaration) $(D =) $(GLINK2 expression, AssignExpression)
3569+ 
3570+ $(GNAME CMainFirstParameterDeclaration):
3571+     $(GLINK ParameterAttributes)$(OPT) $(GLINK CMainFirstParameterBasicType) $(GLINK_LEX Identifier)$(OPT)
3572+ 
3573+ $(GNAME CMainFirstParameterBasicType):
3574+     $(D int)
3575+     $(GLINK2 type, TypeCtor) $(D $(LPAREN)) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK CMainFirstParameterBasicType) $(D $(RPAREN))
3576+     $(GLINK_LEX Identifier)
3577+ 
3578+ $(GNAME CMainNextParameterDeclaration):
3579+     $(GLINK ParameterAttributes)$(OPT) $(GLINK CMainNextParameterBasicType) $(GLINK CMainParameterTypeSuffixes)$(OPT) $(GLINK_LEX Identifier)$(OPT)
3580+ 
3581+ $(GNAME CMainNextParameterBasicType):
3582+     $(D char)
3583+     $(GLINK2 type, TypeCtor) $(D $(LPAREN)) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK CMainNextParameterBasicType) $(GLINK CMainParameterTypeSuffixes)$(OPT) $(D $(RPAREN))
3584+     $(GLINK_LEX Identifier)
3585+ 
3586+ $(GNAME CMainParameterTypeSuffixes):
3587+     $(D *)
3588+     $(D *) $(D *)
3589+ )
3590+ 
3591+     $(NOTE For $(GLINK MainReturnBasicType), the options of returning `noreturn` or an `enum` type are both covered by $(GLINK_LEX Identifier).)
35113592
35123593$(H2 $(LNAME2 function-templates, Function Templates))
35133594
0 commit comments