Boost logo

Boost :

From: Martin Bonner (martin.bonner_at_[hidden])
Date: 2006-12-16 16:44:38


Emil Dotchevski wrote:
> 3.6.2.3: It is implementation-defined whether or not the dynamic
> initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is
> done before the first statement of main. If the initialization is deferred
> to some point in time after the first statement of main, it shall occur
> before the first use of any function or object defined in the same
> translation unit as the object to be initialized.

Yes, but I think you will find that unless the implementation /does/ perform dynamic initialization before the first statement of main, it will have unsolvable ordering problems. Consider a class A defined in a.cpp, and B defined in b.cpp.

a.cpp:
extern B theB;
A::A() { .... }

b.cpp:
extern A theA;
B::B() { .... }

Now then. If something from a.cpp is referenced externally then the compiler must initialize 'theB' before it starts using any of the functions in a.cpp. To do that, it has to execute B::B, which means it must initialize 'theA', which means it must call a function (A::A) in a.cpp ... before it is allowed to use any of the functions in a.cpp.

Therefore dynamic initialization must be done before main.

Note, of course, that this argument assumes no prior undefined behaviour. The particular /form/ of undefined behaviour which is most likely to break it, is loading a DLL.

>> As far as "deadstripping" code - this has indeed been a big problem -
>> especially in release mode. I've referred to it as overzealous
>> optimization.

> It isn't overzealous -- it's within the specifications of the standard,
>whether you like it or not.

Chapter and verse? (Given the above argument that dynamic initialization must happen first.)

Ignoring the above, I agree that a boost library for reliable dynamic registration would be really useful (even if I think the standard says it ought to work, it clearly doesn't work with all real compilers)

-- 
Martin Bonner
Pi Technology, Milton Hall, Ely Road,
Milton, Cambridge, CB4 6WZ
+44 1223 203894
________________________________
From: boost-bounces_at_[hidden] on behalf of Emil Dotchevski
Sent: Fri 15/12/2006 22:51
To: boost_at_[hidden]
Subject: Re: [boost] [Serliazation] Thread-safety again
>> Therefore, you are still prone to threading problems. There is
>> nothing in the C++ standard which guarantees globals will be
>> initialized before main().
>
> According to the reference I use: The C++ Programming Language by
> Stroustrup page 244 10.4.9:
> "A global, namespace or class static object which is created once "at the
> start of the program" and destroyed at once at the termination of the
> program." I've always interpreted this to mean what it says and this is
> reflected in the standard..  But I'm sure some else on this list can give
> a definitive answer as to what the standard actually says.
3.6.2.3: It is implementation-defined whether or not the dynamic
initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is
done before the first statement of main. If the initialization is deferred
to some point in time after the first statement of main, it shall occur
before the first use of any function or object defined in the same
translation unit as the object to be initialized.
> As far as "deadstripping" code - this has indeed been a big problem -
> especially in release mode. I've referred to it as overzealous
> optimization.
It isn't overzealous -- it's within the specifications of the standard,
whether you like it or not.
> Compilers vary quite a bit in this regard and In practice it has been
> addressed on an ad-hoc basis.  In some cases code has been marked
> "_export" just so the optimizer doesn't drop it.  This is the function of
> the module "force_include.hpp".
If I find that a piece of code breaks when optimizations are enabled, I
treat it as a bug. Sometimes it's bug in the compiler, but more often than
not it isn't.
>> In my opinion, the only portable option is to require manual
>> registration,
>
> That may well be true.
>
>> and leave it up to the user to come up with their own,
>> non-portable solution for automatic registration, and deal with
>> multi-threading/deadstripping problems this could cause.
>
> Or the user could use the system included with the serialization library
> which has already dealt with these issues.
The only issue I see here is that you are trying to prevent the compiler
from doing something that the standard allows it to do. Besides (I'm
repeating myself here), the "problem" you are solving is beyond the scope of
the serialization library, because there are other systems that also need
type registration and other one-time dynamic initialization. If there is a
consensus that it is desirable to provide for automatic dynamic
initialization of namespace-scope objects even if no function from their
compilation unit is ever executed, perhaps this needs to be separated in a
boost library of its own, as a first step of (possibly) adding such feature
to the C++ standard.
>> I personally find it easier to register my
>> classes "manually" (note that systems other than the serialization
>> library also require class registration.)
>
> I'm not going to disagree with that.  This was the first method I used and
> it works well and is portable.  But the lack of an automatic method like
> "export" raised a chorus of howls which had to be addressed.
I've seen many instances of chorus of howls from folks that write
sub-standard code and complain that it isn't working as they have hoped. I
tend to quote the C++ standard in response.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk