The Main function

An executable package starts at a function named Main, declared at the top level of the package — outside every module block — and taking no parameters. When Main returns, the program ends, and its result becomes the process's exit status: 0 for success, anything else for failure.

func Main() -> int {
    PrintLine("Hello, Rux!");
    return 0;
}

A new executable package keeps Main in Src/Main.rux, but any file of the package may hold it. Library packages have no Main, and rux run refuses to run one.

The forms

DeclarationEnds byExit status
func Main()reaching its end, or return;0
func Main() -> intreturn n;n
func Main() -> ! Ereaching its end, or return;0
func Main() -> int ! Ereturn n;n
-> ! E or -> int ! Efail, or a failed ?1

E may be any error type. A fallible Main lets ? propagate a failure out of the program:

variant StartError {
    MissingConfig
}

func Load(present: bool) -> int ! StartError {
    if !present {
        fail StartError::MissingConfig;
    }
    return 3;
}

func Main() -> ! StartError {
    let count = Load(false)?;   // fails: the program ends with status 1
    PrintLine("loaded {}", count);
}

On failure, Main runs its ordinary cleanup — deferred statements and destructors — and the process exits with status 1. The error itself is not printed. A program that wants the user to see why it stopped prints a message before it fails, for instance in a catch arm that then fails with the same error.

A panic is different: it stops the program at once, without cleanup, whatever form Main has.

Any other signature — parameters, or a result that is not an integer — is an error:

func Main(count: int) -> bool {
    return true;
}
error: 'Main' must take no parameters and return nothing, an integer, '! E' or an integer '! E', but it takes parameters and returns 'bool8'
  note: the result of 'Main' is the process's exit status, which no other form defines
  help: declare it as 'func Main() -> int', 'func Main() -> ! E' or 'func Main() -> int ! E'

The message names only what is wrong: func Main() -> float64 ends with but it returns 'float64'.

DllMain

A shared library built for Windows (Type = "SharedLibrary") may declare a top-level function named DllMain. The Windows loader calls it when a process loads or unloads the library, and the library loads only if it returns a non-zero value. Its signature is the one Windows expects:

func DllMain(instance: *opaque, reason: uint32, reserved: *opaque) -> int32 {
    return 1;
}

Without a DllMain, the library loads as if one had returned 1. On other systems the name has no special meaning.

See also