Re: Feedback needed, especially non-Linux

David Fang <[email protected]>
Newsgroups gmane.comp.gnu.gnucap.devel
Message-ID <[email protected]>
> On Thursday 22 February 2007 17:23, David Fang wrote:
> >         Ok, it didn't take long to find various comments
> > about link ordering: src/Makefile.am, globals.cc, etc... :)
> >         Link-ordering and global initialization ordering
> > between translation units are not related; you cannot depend
> > on link ordering to influence the other.  When it happens to
> > work, consider yourself lucky!
>
> Actually, it is not guaranteed but is deterministic.  Such
> system dependencies are undesirable but exist more often than
> most of us are willing to admit.  One example is the assignment
> of device names in a unix-type operating system.  Suppose you
> have two ethernet ports.  Which is which?  What order are the
> file systems mounted?
>
> Based on claims of magic, that is one of the things I would
> expect autoconf to take care of.  It does a great job at
> working around the junk of pre-Ansi C, but we still have that
> baggage, and there isn't much there for C++.  It doesn't easily
> handle most C++ issues.

Al,

Correct, unspecified but determinstic.

Global initialization ordering is still beyond the build-system's control,
other than exhaustively trying combinations that work.  This isn't
autoconf's problem, or libtool's problem.  The holy standards of C and C++
simply never laid down the law about this ordering.  Forunately, there are
methods for enforcing proper ordering -- one can ensure correct ordering
for any non-cyclic dependence graph (of globals).

> It has to do with
>
> 1. A container obviously must be initialized before putting
> anything in it.
>
> 2. The objects in that container vary depending on
> configuration.
>
> The container is in globals.cc.  The objects in it are in
> assorted other files which may or may not actually be used.
> You can remove something, just leave it out of the Makefile.
> You can add your own modules, just add it to the Makefile.  No
> other changes are allowed.
>
> If you leave it out, you can add it at run time (like a kernel
> module).  There is no difference between a module that is
> linked at compile time and one that is added later, other than
> whether it is in the Makefile.
>
> Look at the file "Make1" .. It separates out the files that
> apply here.
>
> You will see....
> RAW_SRCS = \
> $(D_SRCS) \
> $(BM_SRCS) \
> $(C_SRCS) \
> md.cc \
> (etc.)
>
> If you remove those SRCS lines, omitting those files, the
> program will still link and run.  It won't do anything, but
> that's ok for now.  A couple of others with the link order
> problem are still there, so it won't fix the link order issue.
> I can deal with it on a small scale.
>
> > I'd advise wrapping access to
> > global variables/structures through some init-once interface,
> > like a function, rather than relying on ordering.  If you
> > need to be precise about global object lifetime, consider
> > using a reference-count pointer to manage orderly
> > destruction. Does this help?
>
> Not sure ...   Remember, it is a requirement that there is no
> difference between a compiled in module and one attached later
> at run time.  It is also a requirement that no tables need to
> be kept in sync.  You are allowed to list it one place, only.
>
> I am leaning toward putting the commands and models in a .so
> file.  The program can start, which initializes the container,
> then load the .so.  The problem with this is that not all
> systems can do dynamic linking.  On these, the plugin feature
> won't work anyway, but it would be nice to still be able to
> build a static linked version.
>
> For an interesting sideline ....  How did they solve this
> problem for iostream?  It isn't documented anywhere, but look
> at the source, you will see.   uh...  Actually you will
> probably still wonder.  The issue on this one is that "cout"
> and friends must work in static constructors, therefore must be
> initialized before any other static constructor.
>
> Speaking of which ...
>
> Consider this program....
> ================
> #include <iostream>
> class foo {
> public:
>   foo() {std::cout << "Hello world\n";}
> } x;
>
> int main() {}
> ================

Solution:

If you need iostream facilities during global initialization (pre-main),
you can guarantee it is set up by inserting:

static const std::ios_base::Init _init;

before uses of std::cout, etc...

> Does it work?
> How?

By the same token, it also makes sure the stream facilities stay alive
long enough during global destruction, (some reference-count like
mechanism) since destruction happens in reverse order (within each
translation unit).



David Fang
Computer Systems Laboratory
Electrical & Computer Engineering
Cornell University
http://www.csl.cornell.edu/~fang/
	-- (2400 baud? Netscape 3.0?? lynx??? No problem!)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.