Public Group

member variable initialization in the header...or not? :S

This topic is 434 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Here's my dilemma, I have this bunch of variable inside a class

protected:
//Window
HINSTANCE mhAppInstance{};
HWND mhWindow{};
std::string mWindowCaption{};
UINT32 mClientWidth{};
UINT32 mClientHeight{};
bool mWindowed{};
bool mMinimized{};
bool mMaximized{};
bool mResizing{};

//Timer
GameTimer mTimer{};
bool mAppPaused{};

//D3D
D3D_DRIVER_TYPE mDriverType{};
ID3D11Device* mDevice{};
ID3D11DeviceContext* mImmediateContext{};
IDXGISwapChain* mSwapChain{};
ID3D11Texture2D* mDepthStencilBuffer{};
ID3D11RenderTargetView* mRenderTargetView{};
ID3D11DepthStencilView* mDepthStencilView{};
D3D11_VIEWPORT mScreenViewport{};

//D3D Settings
bool mEnable4xMsaa{};
UINT m4xMsaaQuality{};

and I have all 0 initiazed them trough curly brackets, but now I was thinking to take it a step further and write inside the  curly brackets the initial state of my bools.

To me this seems perfect because I have a huge list of variables with all their starting states as soon as I open the header page without need to scroll up and down if I where to initialize them inside the cpp, so flipping pages is faster than scroll up and down (at least for me)...but despite this convenience that seems obvious to me, It seems like everyone go and initialize their variable in the constructor.

So I was wondering, I am doing it wrong and there are serious concerns and reason I should know about for not doing it in the way I am or is just a stylistic choice? (I don't think it is since too many people seems doing it that way...)

Edited by MarcusAseth

Share on other sites

Initializing variables like that is only possible from C++11 and onwards. This might explain why you haven't seen it a lot.

There are times where it might be useful (if the variables should always be the same thing, i.e. not default to different things in different constructors/circumstances, etc.), and times were you cannot use it (depends on variables passed in, etc.).

Share on other sites

I see. Christian Hackl in that link mention possible expensive recompilations if one where to change the initial value of a variable specified in a header file, so my super noob question is, there is a way for me inside Visual Studio 2017 to track this recompilation time so that I can do my experiments and just be aware of it?

Edit: oh wait, I can actually google that myself  Pretty sure is a easy to find one

Edited by MarcusAseth

Share on other sites

If you have the initialization in the header, every file that includes that header will have to be recompiled if you change the value.

As for tracking it, just hit compile and see how long it takes.

Share on other sites

Apparently I had the compile time turned off by default (default VS2017 setting), according to Peter Mortensen  the procedure to show it is

Menu Tools  Options  Projects and Solutions  VC++ Project Settings  Build Timing

Nice!

Edited by MarcusAseth

Share on other sites

Small followup, after long reasoning I might have discovered my style for initializing the varibles in a header, and I may also discovered that I have some OCD problems

Rules:

1)Variable names line up under each section, same for the initialization brackets

2) 1 space between the longest type name of a section(marked by a comment) and variable name

3) only nullptr and true/false allowed inside brackets(for now, this may change)

4)initialization brackets line up based on the longest variable name

protected:
//Window
HINSTANCE    mhAppInstance { nullptr };
HWND	     mhWindow	   { nullptr };
std::string  mWindowCaption{};
UINT32       mClientWidth  {};
UINT32       mClientHeight {};
bool         mWindowed	   { true }; //CARE: at the moment we are not actually changing this when not windowed
bool         mMinimized	   { false };
bool         mMaximized	   { false };
bool         mResizing	   { false };

//Timer
GameTimer  mTimer    {};
bool       mAppPaused{ false };

//D3D
ID3D11Device*		mDevice		   { nullptr };
ID3D11DeviceContext*    mImmediateContext  { nullptr };
IDXGISwapChain*         mSwapChain	   { nullptr };
ID3D11Texture2D*	mDepthStencilBuffer{ nullptr };
ID3D11RenderTargetView* mRenderTargetView  { nullptr };
ID3D11DepthStencilView* mDepthStencilView  { nullptr };
D3D11_VIEWPORT	        mScreenViewport    {};

//D3D Settings
bool mEnable4xMsaa  { true };
UINT m4xMsaaQuality {};

Edited by MarcusAseth

Share on other sites

Note that the initialization has a cost. It is small, but it exists.  You can often do the initialization at the same cost -- and possibly at a lower cost -- with your constructor.

Why do you need to initialize mWindowCaption? It is a std::string, it comes properly initialized to empty all by itself.

Are there items on that list that are initialized or set to specific values at other times? For example, you probably are setting the application pointer, the width and height, and a few other D3D values immediately after construction. Why do you blank those out and pay the cost of assigning to them twice?  If proper usage requires you to set them to a value before they are otherwise used, initializing them to a value such as zero or null and then immediately writing to them a second time with the expected value is wasteful.

Share on other sites

My only argument would be that I'm not confident enough I'll remember to initialize everything and I always assume I will fuck up so I just want a second line of defense by just putting { } in front of every variable I declare and not have to think about it anymore.

But is a weak argument I know

Quote

You can often do the initialization at the same cost -- and possibly at a lower cost -- with your constructor.

You mean before the constructor body like

A::A(int value) : variable(value)  // <---this on the left
{

}

or inside the constructor body? Or is the same thing?

Edited by MarcusAseth

Share on other sites

That means with the constructor initializer list. That is the constructorname : variable(value) thing you've got up there.  Be certain they are in the same order as they exist in the class.

Initializing them inside the body takes place after the others, so putting it in the body also incurs the cost of multiple initializations for types that have initializers/constructors.

Initializing them the way you are doing it now does have the benefit of ensuring a value is assigned, at the risk of potentially paying the cost multiple times.  If you're fine with the cost and don't trust yourself, what you've got can work.

Share on other sites

That's useful information

By the way, I'm pretty sure I won't stick with this way of initializate things for long, I will grow past it pretty soon,   performance first.

Edited by MarcusAseth

1. 1
2. 2
3. 3
4. 4
Rutin
12
5. 5

• 12
• 17
• 10
• 14
• 10
• Forum Statistics

• Total Topics
632660
• Total Posts
3007698
• Who's Online (See full list)

There are no registered users currently online

×