Module basics

This section discusses several basic issues related to defining modules, including the top-level module macros and importing other modules.

Definition block start and end macros

Use the A_MODULE macro to start the module definition block:

A_MODULE(modulename, "modulename")

The arguments contain the module name, first unquoted and then in quotes. If a multipart module name such as foo::bar is used, however, the first argument should have the :: operators replaced with underscores like this:

A_MODULE(foo_bar, "foo::bar")

The value of the first argument is also used in the name of the compiled module (foo_bar.so or foo_bar.dll in the above example).

The A_END_MODULE macro must be used to signal the end of the module definition block, after all the definitions. This example illustrates the structure of a module definition, with various details omitted:

A_MODULE(...)
    /* contents of the module defined using various A_* macros */
    A_DEF(...)
    A_CLASS(...)
        A_VAR(...)
        A_METHOD(...)
        A_METHOD(...)
    A_END_CLASS()
    A_DEF(...)
    ...
A_END_MODULE()

Importing modules

Like ordinary modules implemented in Alore, C modules may import other modules. The A_IMPORT macro is used for this purpose:

A_MODULE(example, "example")
    A_IMPORT("re")
    /* contents of the module */
A_END_MODULE()

C modules may import both C and Alore modules, but circular dependencies are limited: there must be no circular dependencies between any two C modules.

A circular dependency between an Alore and a C module, however, is possible. It is actually a common implementation technique for creating effectively mixed C/Alore modules, as explained in section Mixing Alore and C in modules.

Visibility of global definitions

Unlike in Alore code, C modules may access both public and private global definitions in all modules that are imported anywhere in the program. The A_IMPORT macro therefore does not affect the visibility of definitions. The macro is still important, however, since it ensures that the imported module is loaded into memory — if a module is never imported in a program, any definitions defined in it are not accessible at all. This affects several API functions, including but not limited to AGlobal and ACall.

As an exception, the module that defines the target type of the A_INHERIT macro must be explicitly imported (unless the superclass is defined in the std or the current module).