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) |
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.
Return to the
comp.compilers page.
Search the
comp.compilers archives again.