Static class member throws an exception when constructed

2

I have a class which contains a static member of another class.

Foo.h
class Foo
{
static DirectXRes dxres;
};
Foo.cpp
DirectXRes Foo::dxres;  // may throw an exception
DirectXRes.h
#include <SDKDDKVer.h>

#ifndef WINVER 
#define WINVER  0x0A00
#endif


#ifndef _WIN32_WINNT
#define _WIN32_WINNT    0x0A00
#endif

#define WIN32_LEAN_AND_MEAN
#define NOMINMAX

#include <Windows.h>
#include <Windowsx.h>

#pragma comment (lib, "d2d1.lib")
#pragma comment (lib, "Dwrite.lib")
#pragma comment (lib, "Windowscodecs.lib")
#pragma comment (lib, "Ole32.lib")
#pragma comment (lib, "Shlwapi.lib")
#pragma comment (lib, "Crypt32.lib")
#pragma comment (lib, "d3d11.lib")

#include <d2d1.h>
#include <d2d1_1.h>
#include <d2d1_2.h>
#include <d2d1helper.h>
#include <d2d1_2helper.h>
#include <dwrite.h>
#include <wincodec.h>
#include <d3d11_1.h>

class DirectXRes
{
     DirectXRes()
      : D2DFactory(nullptr),
        WriteFactory(nullptr),
        ImgFactory(nullptr),
        D3DDevice(nullptr),
        ImmediateContext(nullptr),
        D2DDevice(nullptr),
        DXGIAdapter(nullptr),
        D2DContext(nullptr),
        DriverType(D3D_DRIVER_TYPE_NULL),
        FeatureLevel(D3D_FEATURE_LEVEL_11_0)
    {
    }

        ID2D1Factory1* D2DFactory;          // Direct2D factory
        IDWriteFactory* WriteFactory;       // DWrite factory
        IWICImagingFactory* ImgFactory;     // Windows Imaging Component (WIC) factory
        ID3D11Device* D3DDevice;            // Direct3D device
        ID2D1Device* D2DDevice;             // Direct2D device
        ID2D1DeviceContext* D2DContext;     // Direct2D device context
        ID3D11DeviceContext* ImmediateContext;  // Direct3D immediate context
        IDXGIAdapter* DXGIAdapter;              // DXGI adapter
        D3D_FEATURE_LEVEL FeatureLevel;         // Direct3D feature level
        D3D_DRIVER_TYPE DriverType;             // Direct3D driver type
};

The problem I has is that if I implement the constructor outside the header file (DirectXRes.h), that is in DirectXRes.cpp I get an exception when the static object is constructed:

Unhandled exception at 0x7550DAE8 (KernelBase.dll) in Viewer.exe: 0xE0434352 (parameters: 0x80131016, 0x00000000, 0x00000000, 0x00000000, 0x71F80000).

While if I keep the implementation of the class constructor in the header file everything works just fine.

Is there any explanation for this exception?

c++
exception
static
directx
asked on Stack Overflow Jul 7, 2016 by Nick • edited Jul 7, 2016 by Cheers and hth. - Alf

1 Answer

2

I think the problem here is static initialisation order. With static variables such as the one in your example, the standard does not specify the order in which they should be initialised, so this can vary. It is most likely that by moving the code from the header file to the cpp file, you inadvertently change the order of initialisation of Foo::dxres relative to something else that uses it. In one version, the thing that uses it is initialised after, and in the other (the one that crashes) it is initialised before, causing it to access an uninitialised Foo::dxres which causes the crash.

If it is possible to change the design, I would make Foo::dxres accessible through a static getter member function instead. This way it will be guaranteed to be available the first time something wants to use it:

class Foo
{
public:
    static DirectXRes& getDxres();
};

//In either the header or cpp:
DirectXRes& Foo::getDxres()
{
    static DirectXRes dxres;
    return dxres;
}
answered on Stack Overflow Jul 7, 2016 by Smeeheey

User contributions licensed under CC BY-SA 3.0