Next Previous Contents

9. Module constructors/destructors

Note: This section applies mostly to C programs, so the explanation below uses examples from the C libraries. However, the feature may also be useful for assembler programs.

9.1 Overview

Using the .CONSTRUCTOR and .DESTRUCTOR keywords it it possible to export functions in a special way. The linker is able to generate tables with all functions of a specific type. Such a table will only include symbols from object files that are linked into a specific executable. This may be used to add initialization and cleanup code for library modules.

The C heap functions are an example where module initialization code is used. All heap functions (malloc, free, ...) work with a few variables that contain the start and the end of the heap, pointers to the free list and so on. Since the end of the heap depends on the size and start of the stack, it must be initialized at runtime. However, initializing these variables for programs that do not use the heap are a waste of time and memory.

So the central module defines a function that contains initialization code and exports this function using the .CONSTRUCTOR statement. If (and only if) this module is added to an executable by the linker, the initialization function will be placed into the table of constructors by the linker. The C startup code will call all constructors before main and all destructors after main, so without any further work, the heap initialization code is called once the module is linked in.

While it would be possible to add explicit calls to initialization functions in the startup code, the new approach has several advantages:

  1. If a module is not included, the initialization code is not linked in and not called. So you don't pay for things you don't need.
  2. Adding another library that needs initialization does not mean that the startup code has to be changed. Before we had module constructors and destructors, the startup code for all systems had to be adjusted to call the new initialization code.
  3. The feature saves memory: Each additional initialization function needs just two bytes in the table (a pointer to the function).

9.2 Pitfalls

When creating and using module constructors and destructors, please take care of the following:


Next Previous Contents