@@ -3420,82 +3420,120 @@ $(H2 $(LNAME2 main, The $(D main) Function))
3420
3420
It gets called after all the $(DDSUBLINK spec/module, staticorder, module initializers)
3421
3421
are run, and after any $(DDLINK spec/unittest, Unit Tests, unittests) are run.
3422
3422
After it returns, all the module destructors are run.
3423
- The $(D main) function typically is declared as follows:
3424
3423
)
3425
3424
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
+ )
3437
3428
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`.
3442
3431
3443
3432
$(UL
3444
3433
$(LI If `main` returns `void`, the OS will receive a zero value on success.)
3445
3434
$(LI If `main` returns `void` or `noreturn`, the OS will receive a non-zero
3446
3435
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.)
3447
3439
$(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 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, e.g., `char[][]` and `immutable(string)[]` are 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`.
3449
3450
)
3450
3451
3451
3452
$(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
3453
3455
the executable name, followed by any command-line arguments.)
3454
3456
3455
3457
$(NOTE The runtime can remove any arguments prefixed `--DRT-`.)
3456
3458
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
-
3461
3459
$(P The main function must have D linkage.)
3462
3460
3463
3461
$(P Attributes may be added as needed, e.g. `@safe`, `@nogc`, `nothrow`, etc.)
3464
3462
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) $(D $(RPAREN)) $(GLINK FunctionAttributes)$(OPT) $(GLINK MainFunctionBody)
3468
+ $(GLINK2 declaration, StorageClasses) main $(D $(LPAREN)) $(GLINK MainParameters) $(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) = $(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
+
3465
3506
$(H2 $(LNAME2 betterc-main, $(D extern(C)) $(D main) Function))
3466
3507
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
3468
3509
standard $(RELATIVE_LINK2 main, entry point). This form is required for
3469
3510
$(DDLINK spec/betterc, Better C, $(B BetterC)) programs.)
3470
3511
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:)
3472
3513
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
+ )
3481
3519
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.)
3485
3521
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.)
3488
3526
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
3492
3530
using the appropriate $(DDSUBLINK phobos/core_runtime, Runtime, runtime functions).)
3493
3531
3494
3532
$(IMPLEMENTATION_DEFINED Other system-specific entry points may exist, such as
3495
3533
`WinMain` and `DllMain` on Windows systems.
3496
3534
)
3497
3535
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
3499
3537
a function with $(DDSUBLINK spec/pragma, mangle, explicit mangling):
3500
3538
3501
3539
---
@@ -3505,9 +3543,52 @@ $(GNAME CMainParameters):
3505
3543
return 0;
3506
3544
}
3507
3545
---
3508
-
3509
3546
)
3510
3547
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) = $(GLINK2 expression, AssignExpression)
3565
+
3566
+ $(GNAME CMainNextParameter):
3567
+ $(GLINK CMainNextParameterDeclaration)
3568
+ $(GLINK CMainNextParameterDeclaration) = $(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) $(LPAREN) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK CMainNextParameterBasicType) $(GLINK CMainParameterTypeSuffixes)$(OPT) $(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).)
3511
3592
3512
3593
$(H2 $(LNAME2 function-templates, Function Templates))
3513
3594
0 commit comments