# Again Inclusion question

## Recommended Posts

Hi guys, I would like to have the header below:

Paths.h

#pragma once
#include <string>

namespace Paths {

namespace Images {
static std::string CHECKER = "Graphics/Checker.png";
}

namespace Fonts {
static std::string BUBBLEBATH = "Fonts/BUBBLEBATH.ttf";
}

}

Included all around the place so that I can do stuff like Paths::Images::CHECKER to easily load the proper file or to request it again by passing that to a map as a key.

Though this I believe create a copy of the static string for every compilation unit, am I correct? Meaning I include it in 10 cpp and get 10 copies of each string.  How would I do this the proper way?

##### Share on other sites
Posted (edited)

Change the "static" with "const"? Or don't use static and const if you still want to be able to change these strings.

If static is used outside of a function or class, it ensures the variable/function can only be used by code in that specific file (translation unit to be precise), and nowhere else. const variables are prevented from changing.

Furthermore, use lower case characters for globals. Most programmers use full upper case for macros. You coud use something like g_checker and g_bubblebath to explicitly indicate these variables are global (though scoped to some namespace). Alternatively, you can consider to use macros for these file names if you intend to add hundreds of them to your code. This will reduce your memory usage.

Edited by matt77hias

##### Share on other sites
Posted (edited)

@matt77hias that doesn't solve the problem.

Anyone knows how to avoid multiples copies being created for every single variable?  :\

Edited by MarcusAseth

##### Share on other sites
Posted (edited)

The exact answer depends on compiler and options you use. Duplicates can be eliminated by compiler/linker, especially if LTO (Link Time Optimization) can be used.

Apparently C++17 introduces inline variables.

inline const std::string my_string = "MyString";

Edited by matt77hias

##### Share on other sites

Ok I think I've figured it out myself, extern to the rescue

Paths.h

#pragma once
#include <string>

namespace Paths {

namespace Images {
extern std::string CHECKER;
}

namespace Fonts {
extern std::string BUBBLEBATH;
}

}

Paths.cpp

#include "Paths.h"

std::string Paths::Images::CHECKER = "Graphics/Checker.png";
std::string Paths::Fonts::BUBBLEBATH = "Fonts/BUBBLEBATH.ttf";

##### Share on other sites
header file

namespace Paths {

namespace Images {
extern std::string CHECKER;
}

namespace Fonts {
extern std::string BUBBLEBATH;
}

}
source file
#include <Paths.h>

namespace Paths {

namespace Images {
std::string CHECKER = "Graphics/Checker.png";
}

namespace Fonts {
std::string BUBBLEBATH = "Fonts/BUBBLEBATH.ttf";
}

}

##### Share on other sites

@AxeGuywithanAxe I've beaten you by few seconds  But thanks

Also, any major differences in the way I did it above and in the way you did it? Or is a style choice?

##### Share on other sites
1 minute ago, MarcusAseth said:

@AxeGuywithanAxe I've beaten you by few seconds  But thanks

Also, any major differences in the way I did it above and in the way you did it? Or is a style choice?

Yeah, i saw that.. haha... not a difference, just style choice and laziness (I just copied and pasted your original comment and added extern and removed static , etc)

##### Share on other sites

I've learned about extern today and suddenly it became my favourite C++ keyword I think

##### Share on other sites
44 minutes ago, MarcusAseth said:

I've learned about extern today and suddenly it became my favourite C++ keyword I think

Until you discover the static initialization order fiasco.

Generally I create free functions to provide well-known constant values that cannot just be constexprs.

##### Share on other sites
Posted (edited)
7 minutes ago, jpetrie said:

Generally I create free functions to provide well-known constant values that cannot just be constexprs.

@jpetrie can you show me an example of one of this free function?

I would like to understand where my global variables should end up living, at which point during executing are they initialized, how this free functions get to them and how all the other files get to this free functions ^_^'

Edited by MarcusAseth

##### Share on other sites

Simplest form is to create them inside main(), and pass them around as needed. You could make a class for them, so related variables are close together.

It's not a real global, but you have much more control over them, and you have to make explicit that some code relies on them, which will one day help in refactoring code (ie avoid the case that you got all parameters, and then find out code also has a huge number of dependencies on globals you completely forgot about.)

##### Share on other sites
Posted (edited)
32 minutes ago, Alberth said:

Simplest form is to create them inside main(), and pass them around as needed.

Not a big fan of that, some object are just too widely used like App for requesting textures to it and Game to allow entity to interact with other entities in the game or the global paths to be used for loading and requesting textures to App (in the code above), I wouldn't want to pass this stuff down constructors and inheritance chains just to end up storing a pointer to each one of them inside of every object or something. And this in case I have understood what you are saying correctly, for me is always hard without a concrete code example to backup an explanation. :\

Edited by MarcusAseth

##### Share on other sites
2 hours ago, MarcusAseth said:

Not a big fan of that, some object are just too widely used

That fact, that they are "widely used," is indicative of a design failure. In a non-trivially-sized project, there are very few things that actually "need" to be accessed from anywhere.

Passing dependencies around like Alberth is suggesting is the better way that making a ton of secret globals. It makes dependencies clear, allows you to enforce contracts in your interfaces, and so on. Globals are impossible to control effectively and impossible to reason about.

3 hours ago, MarcusAseth said:

can you show me an example of one of this free function?

"SomeThing getSomeThing() { return SomeThing(value, of, some, thing); }" if SomeThing has value semantics or "SomeThing& getSomeThing() { static SomeThing result(value, of, some, thing); return result; }" if it's more complex, et cetera.

##### Share on other sites
Posted (edited)

@jpetrie sorry, still not clear ^_^' I guess I am missing the bigger structure here, where everything is placed in comparison to everything else, like in which header is this function compared to who calls it, where are the things result is builted with taken from and how you reach them and so on...

SomeThing& getSomeThing()
{
static SomeThing result(value, of, some, thing);
return result;
}

so this above is the function.

So from what I am understanding, in practice would look something like this, and it will live in the Global.h:

Global.h

#include "App.h"
#include "SDL2\SDL.h"

struct AppInfo {
App* App;
GameMode* Game;
SDL_Window* Window;
SDL_Renderer* Renderer;
Uint32 Width, Height;
};

AppInfo& GetAppInfo()
{
static AppInfo result{MyApp.GetApp(), MyApp.GetGame(), MyApp.GetWindow(), MyApp.GetRenderer(), MyApp.GetWinWidth(), MyApp.GetWinHeight()};
return result;
}

But the problem is, when is that static initialized?! If it is when I run the program, then App wouldn't be initialized yet... is that the case? If so, then I still don't get it how to do it...

Furthermore, where is this "App MyApp"  global object created and initialized, I mean where is living? :\

The example is still too abstract for my brain, the problem is I can't see the entire structure pattern here... :\

Edited by MarcusAseth

##### Share on other sites

Why not cut using "variables" completly for string constants and use some inline accessor function to grab it?

namespace MyGame
{
namespace Constants
{
inline const char* Files() { return "./Assets"; }
inline const char* OpenGl() { return "./Lib/OpenGl.dll"; }
}
}

...

void* gl_lib = (void*)LoadLibraryA(MyGame::Constants::OpenGl());

Any clever compiler (and I think even MSVC should solve this) optimizes the inline call away for a pure string constant access without any considerable overhead

##### Share on other sites
Posted (edited)

@Shaarigan if I understand correctly what you're saying, that's seems messy to me because then I have to compose in place the name of the thing I want to load like string(MyGame::Constants::Files()) + "Graphics/Checker.png" and I have to remember the name of stuff all over the place, much easier to just call Paths::Images::CHECKER and let it do the right thing.

Edited by MarcusAseth

##### Share on other sites
1 hour ago, MarcusAseth said:

string(MyGame::Constants::Files()) + "Graphics/Checker.png"

Let it return a const std::string instead of a const char *. Then you can already slightly reduce it to

MyGame::Constants::Files() + "Graphics/Checker.png", which looks pretty reasonable (assuming you do not perform this a million times per second).

##### Share on other sites
Just now, matt77hias said:

Let it return a const std::string instead of a const char *. Then you can already slightly reduce it to

MyGame::Constants::Files() + "Graphics/Checker.png", which looks pretty reasonable (assuming you do not perform this a million times per second).

Looks still pretty bad to me...All I am doing right now to load an image is this:


LoadTexture(Paths::Images::CHECKER);

and to get it from another file,

Checker::Checker(float x, float y):
Tile(x,y,Paths::Images::CHECKER)
{
}

The fact I write it in 2 different places increase chances for mistakes if I where to manually write it.

This way, I simply cannot make a mistake, and if I mispell it inside the Paths.h, then that error get caught by the LoadTexture.

##### Share on other sites
Posted (edited)
4 minutes ago, MarcusAseth said:

The fact I write it in 2 different places increase chances for mistakes if I where to manually write it.

Fair point, but what if you want to change the directory of your assets? How many changes does that inccur at the moment?

You could also encapsulate your resources in some object which provides a method for retrieving the filename, file name and file path. And then you can pass a reference to the resource object around. This avoids the need for duplicating the concatenation everywhere.

Edited by matt77hias

##### Share on other sites
2 minutes ago, matt77hias said:

Fair point, but what if you want to change the directory of your assets? How many changes does that inccur at the moment?

Exactly 1.  Hold ALT pressed inside of visual studio, do a rectangle box selection, write the new directory name. And this is why I have them all lined up inside a single file. The way you guy suggest, request go inside of each and every file 1 by 1 and fix it.

##### Share on other sites
Posted (edited)
8 minutes ago, MarcusAseth said:

Exactly 1.  Hold ALT pressed inside of visual studio, do a rectangle box selection, write the new directory name. And this is why I have them all lined up inside a single file. The way you guy suggest, request go inside of each and every file 1 by 1 and fix it.

Ok but in Software Engineering a change is a change independent of some solution (.sln) wide global search-and-replace (which does multiple changes for you). The latter is some handy utility to help you do it efficiently, but it is no remedy for the disease (referring to implicit dependencies).

Edited by matt77hias

##### Share on other sites
15 hours ago, matt77hias said:

inline const std::string my_string = "MyString";

Thought of using this today, but VSC++ compiler team is lagging behind

##### Share on other sites

Why are you loading textures manually in one place, but also passing the path in a different (seemingly unrelated) place? Your original post says it's to be able to request the texture again, but why would you ever want that?

I would have expected the tile to only hold a pointer to its texture. Upon creation, load the texture (if need be, have some caching system or similar to prevent multiple loads of the same texture) and store a pointer to the texture in each tile/object.

##### Share on other sites

I wouldnt trust C++11/14/17 support anyways but thats another topic.

To quote Hodgman, game IO should be a lot more limited than generic IO and so your game should anyways NOT use full paths to read Assets from disk. What I do in my framework is to set a fixed working directory and address my assets relative to that using "./" if necessary  (to address packages)

I do not fully understand objections because however you change paths/files, you do it in one single file used in many other files anyways so changing a string constant or function return should be regardless. However, global string constants have disadvantages as mentioned in any above post due to initialization order and local unit copies where inline header functions are optimized away mostly and directly accessed without code impact. Another option is for sure using macro constants so you wont have any access overhead.

It is ok for small projects and debugging code to go for direct file access but in medium or larger ones there should at least be some kind of package for disk aligning and IO performance reasons

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628307
• Total Posts
2981972
• ### Similar Content

• By HD86
As far as I know, the size of XMMATRIX must be 64 bytes, which is way too big to be returned by a function. However, DirectXMath functions do return this struct. I suppose this has something to do with the SIMD optimization. Should I return this huge struct from my own functions or should I pass it by a reference or pointer?
This question will look silly to you if you know how SIMD works, but I don't.

• Hey, Im using directx allocate hierarchy from dx9 to use a skinned mesh system.
one mesh will be only the skeleton with all animations others meshes will be armor, head etc, already skinned with skeleton above. No animation, idle position with skin, thats all I want to use the animation from skeleton to other meshes, so this way I can customize character with different head, armor etc. What I was thinking its copy bone matrices from skeleton mesh to others meshes, but Im a bit confused yet what way I can do this.

Thanks.

• Does buffer number matter in ID3D11DeviceContext::PSSetConstantBuffers()? I added 5 or six constant buffers to my framework, and later realized I had set the buffer number parameter to either 0 or 1 in all of them - but they still all worked! Curious why that is, and should they be set up to correspond to the number of constant buffers?
Similarly, inside the buffer structs used to pass info into the hlsl shader, I added padding inside the c++ struct to make a struct containing a float3 be 16 bytes, but in the declaration of the same struct inside the hlsl shader file, it was missing the padding value - and it still worked! Do they need to be consistent or not? Thanks.
struct CameraBufferType
{
XMFLOAT3 cameraPosition;
};
• By esenthel
Just finished making latest WebGL demo for my game engine:
http://esenthel.com/?id=live_demo
Let me know what you think,
as of now only Chrome and Firefox can run it.
Edge, Safari, Opera have some unresolved bugs at the moment.
• By reders
Hi, everyone!
I "finished" building my first game. Obviously Pong.
It's written in C++ on Visual Studio with SFML.
Pong.cpp
What do you think? What should I consider doing to improve the code?
Thank you very much.

EDIT: added some screenshot and .zip file of the playable game

Pong.zip

• 9
• 13
• 11
• 12
• 11