Re: VS2008 destroys static objects before global (non-static) objects?



On Wed, 22 Oct 2008 13:28:30 +0200, Ulrich Eckhardt <eckhardt@xxxxxxxxxxxxxx> wrote:

Boris wrote:
Can anyone confirm that the function _CRT_INIT has been changed from
VS2005 to VS2008 in such a way that static objects are now destroyed first
before global (non-static) objects are destroyed? Looking at the latest
C++ standard draft this seems to be permitted (and would explain why I see
a crash when closing a software which I just upgraded from VS2005 to
VS2008).

I can't confirm nor deny that particular change, but the initialisation
order of globals in different translation units has always been
unspecified, hence the so-called "initialisation order fiasco". Other than
that, objects are generally destroyed in the opposite order of their
creation and at least function-static objects are therefore always
destroyed before globals. What kind of static are you referring to?

My problem explained in pseudocode is this:

----------
template <typename T>
class memory_manager
{
public:
void *operator new(std::size_t) { return mem_p_.malloc(); }
void operator delete(void *p) { p_.free(p); }

private:
static pool p_;
};

class small_object : public memory_manager<small_object>
{
};

std::auto_ptr<small_object> o(new small_object());
----------

While the class definitions are in one DLL o is defined in another DLL (let's call them 1.dll and 2.dll where 1.dll depends on 2.dll). When the DLLs are loaded p_ in 2.dll is initialized first followed by an initialization of o and again p_ in 1.dll (at least that's what I see when stepping through the DLL initialization code; maybe I'm wrong here as I don't fully understand what Microsoft is doing there in crtdll.c and crt0dat.c). When the DLLs are unloaded everything is uninitialized but in reverse order. As the destructor of p_ is then called first which frees all memory managed by the memory manager I get an access violation when o is destroyed.

The code worked fine for years with VS2005 (and also g++ on Linux). If the initialization and destruction order was really changed in VS2008 I need to think about how to adapt the code. :-/

Boris
.



Relevant Pages

  • Re: creating a c++ dll
    ... you might have a DLL that relies only on the C ... >> initialization of static duration objects (globals and class statics) ... >> DLL Y can be assured Y's globals are initialized before X's. ... initialization order of globals defined in different translation units. ...
    (microsoft.public.vc.language)
  • Re: P-Invoke + IJW Failure
    ... of our early initialization code, native and managed, and we will be looking ... dependency loops in the DLL load order. ... routine before calling any other routines in the DLL. ... a slightly modified DLL load order or other factors may ...
    (microsoft.public.dotnet.framework.interop)
  • Re: error R6031
    ... When called _CRT_INIT on initialization, in crtdll.c at line: ... The fact that you have what appears to be a statically-linked CRT in a DLL (I'd suggest ... debugger was awakened by an interrupt. ...
    (microsoft.public.vc.mfc)
  • Re: error R6031
    ... I tried to debug _DllMainCRTStartup and __DllMainCRTStartup. ... When called _CRT_INIT on initialization, in crtdll.c at line: ... The fact that you have what appears to be a statically-linked CRT in a DLL (I'd suggest ... It is amazing that on application exit system calls DllMainCRTStartup. ...
    (microsoft.public.vc.mfc)
  • Re: Initialize dynamic allocated data before main get error?
    ... these kind of initialization is called static initialization. ... int* foo{ ... problems you will get from using globals a lot. ...
    (alt.comp.lang.learn.c-cpp)