C Extension - Initializers and Finalizers

utzoo!decvax!yale-com!leichter utzoo!decvax!yale-com!leichter
Sun Oct 31 19:15:10 AEST 1982

This newsgroup got started to discuss proposed extensions to C.  It seems
to have gotten bogged down in detail discussions of bracketing strategies.
Herein is an attempt to return the discussion to something a bit meatier.
The following is (essentially) a man page describing an extension I added
recently to DECUS C.  It was very simple to implement and I've found it
quite useful.  (Note that this isn't yet in any distributed copies of
DECUS C; don't go off and try to find it!)

BTW:  Note the challenge in the BUGS section!
						-- Jerry
					leichter @ yale

        1.0  Specify Initializers and Finalizers
             ------- ------------ --- ----------

                                  * initial *

        NAME:   initial -- Specify Initializers and Finalizers


                 #include <initia.h>

                 { initial-code-block };

                 { final-code-block };


                The macros defined in this module provide a facility for
                module-specific  initialization  and  finalization code.
                The code in the initial-code-block is called as a normal
                C    function    before    main()    is   called;    the
                final-code-block is called on exit, just after wrapup().

                Neither call passes any arguments.

                Any number of modules  in  an  image  may  independently
                declare initializers or finalizers;  all of them will be
                called at startup or exit.  However, it is impossible to
                predict  what  order  the  calls  will  be  made in, and
                programs should not rely on any particular ordering.

                A typical use of  initializers  and  finalizers  is  the
                following:   Suppose  you  have  a package that supports
                access to some on-disk data base;  a user of the package
                will  call  a  lookup  and an update function.  The file
                containing the data  base  must  be  opened  before  any
                operations on it can take place, and it should be closed
                when the program is finished.  (Assume that the  package
                maintains  some  sort  of  resident buffer which it must
                flush.) There are two conventional approaches to solving
                this  problem:   Have  the  lookup  and update functions
                check the file on each call, and open it if necessary  -
                which  could  be  quite expensive if they are very small
                functions, and in any case does not solve the problem of
                properly  closing  the  file  - or have the main program
                call an initialization and finalization function at  the
                                                                          Page 2
        initial Specify Initializers and Finalizers

                proper  time.   The problem with this latter approach is
                lack of modularity - the main program ought not to  have
                to   know   that  the  module  needs  initialization  or

                The solution using these macros is straightforward.  The
                defining module includes the calls:

                        { open-the-data-base };

                        { flush-buffers-and-close-the-data-base };

                Note:  Using INITIAL  will  declare  a  static  function
                named $init$(), and a (char *) named $init_;  similarly,
                FINAL will declare  $finl$()  and  $finl_.   Also,  both
                INITIAL  and  FINAL  generate  dsect  commands.  Since C
                provides no way to "remember" the  current  dsect,  both
                macros  issue  a  dsect  ""  command when they are done,
                restoring the C default dsect.

                If  a  user-written  wrapup()  function   calls   exit()
                recursively,  any  finalizers  declared  will  still  be
                called;  however, if any  finalizer  calls  exit(),  the
                program exits immediately.


                Requires  the  DECUS  C  dsect  commands;   hence,  very
                non-portable.   It  may  be possible to provide the same
                functionality  using  different  techniques;   if   not,
                what's wrong with your implementation?


                Jerry Leichter

More information about the Comp.lang.c mailing list