Re: How should compilers sequence static initialization of objects/methods

Andrew Fry <andrewf@slhosiery.com.au>
30 Nov 1998 02:11:53 -0500

          From comp.compilers

Related articles
How should compilers sequence static initialization of objects/methods KittyCrap@severins-child.demon.co.uk (Rachel-Louise Koktava) (1998-11-24)
Re: How should compilers sequence static initialization of objects/met andrewf@slhosiery.com.au (Andrew Fry) (1998-11-30)
Re: How should compilers sequence static initialization of objects/met jason@cygnus.com (Jason Merrill) (1998-11-30)
| List of all articles for this month |
From: Andrew Fry <andrewf@slhosiery.com.au>
Newsgroups: comp.compilers
Date: 30 Nov 1998 02:11:53 -0500
Organization: Hilton Hosiery Company
References: 98-11-123
Keywords: C++, linker

John,


> [Usually it generates anonymous routines that do the initialization,
> and the linker somehow collects pointers to all those routines so the
> program startup code can call them all. I gather that implicit
> ordering dependencies are a chronic source of wierd and hard to
> diagnose errors, and the standard advice about how to force a
> particular order of initializers is "don't do that". Reports of
> counterexamples if they exist would be appreciated, since I'm working
> on that part of the linkers book. -John]


Some time ago, while working on a proprietary language system, I came
across the same problem.


Each module M (there were *many* in a typical compilation/linkage) had
an initializer (and maybe a destructor) - that depended on the
initializers/destructors of all the modules imported by M, and so on.
The initializers were listed in the symbol table.


At link time, the names of the initializers were added to the end of a
list; unless they were already named, in which case their name was
moved to the end of the list. Each module import list was processed
recursively and I ended up with a list of initializers, with the ones
needed first at the end of the list. Main() called the last (first
needed) initializer; once initialized, it called the previous one, and
so on up the list. The very first item on the list was the
application's main routine. Destructors were handled by having the
constructor perform the destructor code when returning.


Initializer[] = (UsersMainProc, LastNeededInit, ...,
                                                SecondNeededInit, FirstNeededInit);
-- filled in at link time


main() -- actual main(), not the user's main
...
     call Initializer[LastInitNum](LastInitNum-1)
...


initializer(InitNum)
initialize
call Initializer[InitNum](InitNum-1)
clean-up -- only if a destructor is specified


UsersMainProc()
...
user code
...


I ended up with a system that performed all initialization in
dependency order, cleaned up in reverse order and was handled at link
time.


The (static) value of the Initializer list was constructed by the
linker (actually by compiling a fragment of C code,) everything else
didn't change and was generated at compile time.


If you're interested in the details, I've probably got the doco and
code lying around somewhere!
Andrew.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.