I have a C++ DLL with 3 classes in it. I added a static boolean variable to my "stdafx" header file (since all of my classes include it) and am trying to use it. While all of my classes see my variable, they each seem to have a different instance of it. If I set the variable to true in once class then I'll notice that it's false in another class. Is there any way that I can create a variable that can be used across all classes only within the DLL?
Well, you labelled it static, so that's what happens. Instead, label it extern in headers and define it in one TU.
And don't modify stdafx; it's not yours. Use your own shared headers.
Your variable is static and you're declaring it in stdafx.h which is included by all source files in your project. This means each translation unit will contain its own copy of the variable, which is exactly the behavior you're seeing.
To solve this problem, declare the variable in stdafx.cpp
bool MyBool = false;
Then extern it in stdafx.h
extern bool MyBool;
Related
I have a multi-file program consisting of
main.cpp
ext1.cpp
ext2.cpp
ext3.cpp
vars.h
As the name suggests, main.cpp is the main file, extX.cpp contains various functions and vars.h some global constants.
However, in main.cpp there are also (a few!) variable declarations, but they must only be within the scope of main.cpp -- that is why I haven't placed them in vars.h
I want to reduce the amount of code in main.cpp (for clarity-issues). I am looking for a way to declare these variables inside a header of some sort, but in a way that it is only visible to main.cpp.
Is it correctly understood that if I place them all inside e.g. vars_main.h (with no external keyword) and just include "vars_main.h", then I have achieved my goal?
Is it considered to be "correct" C++-style to do it this way?
If those variables are used only in main(), then yes, you could do that. But I would not go as far as considering it a "correct C++ style".
If one day you will end up including that header file into another translation unit (maybe because you will need to share just one of those variables), the linker will start complaining about multiple definitions.
At that point, to overcome this, you could use the static keyword to give those variables internal linkage and workaround the problem of multiple definitions. This way, however, each translation unit (.cpp file) will hold its own copy of those variables, which is probably not what you want, especially if they are not constant - just for the record, global constants have internal linkage by default, so you won't need to explicitly qualify them as static.
The normal practice here is either to leave those variable definitions in main(), or to have one header which contains only extern declarations of those variables, and one translation unit that contains their definitions. Then, all the files which need to access those variable would just import the header with the declarations.
The usual practice would be to go ahead and define them in main.cpp, since they're in a distinct block and won't affect the readability of the code. However you can certainly move them out to a separate include file that's only included in one .cpp, that's a stylistic choice that's completely up to you.
If the variables you are talking about are global variables private to main, I think that you should let them in main.cpp. If they are not used anywhere else, it does not make sense to declare them in a header
You could also create a class implementing the "main" features with your variables in private scope so that they won't be used by other parts of the implementation .
I'm writing a game framework and I'm trying to generalize and encapsulate platform dependent code like the renderer so that it makes it a bit easier to port. I'm trying to accomplish this while still having a clean way of using the framework. I'm currently having a problem with static variables and namespaces...
// Renderer.h
namespace Renderer
{
static IRenderer* g_pRenderer = NULL;
static IRenderer* Get(void) { return g_pRenderer; }
static IRenderer* CreateD3DRenderer()
{
g_pRenderer = new RendererD3D(); // Derived from IRenderer
return g_pRenderer;
}
}
So in my main(), I can call CreateD3DRenderer() and it returns an instance just fine; g_pRenderer is holding its value since it's being created and returned within the scope of its function... However, Renderer::Get() returns NULL. Removing 'static' from the init of g_pRenderer causes clashes when used in other files.
What's going on?
First off, void in an argument list is only necessary in C. In C++, you'd just write Get().
As for the main question, static variables are restricted to the compilation unit. Since you put them in a header, this results in a separate variable being created for every compilation unit (i.e. every cpp file) where it is included. You get errors when you remove the static part because then you have multiple variables with the same name, leading to a linking error.
If you want a single variable to be shared between multiple files, you use extern. However, this is considered bad practice. You're better off refactoring so you don't need global variables like that.
You should keep all definitions of functions in .cpp files, instead of .h
What is happening is that when static is used in that fashion, the function or variable is restricted to that .cpp file, which means that g_pRenderer is different in each .cpp file. Multiple definition doesnt happen since each definition is restricted to one .cpp file.
You need to remove it to get your global pointer to work. You can keep the static on the getter function, but I would remove it. You should move the definition of the function and the global variable to a .cpp file and keep just a declaration of each in the .h. Declare the variable as extern.
The header file contains two variables.
Because of the structure of my program, I have two "ld: duplicate symbol" errors.
These two variables have only local significance.
Is there any way of making these variables "private", so they wouldn't be seen outside of the header file even if the header file is included to another source file?
EDIT: please tell me, would it be nice if I will put the variables to the cpp file? These variables are very big arrays, defined while initializing, and take a lot of lines of code...
extern char Lookup[][3] = { "aa", "ab", "ac", "ad", "ae", "af", ... and so on (really long)}
The solution is to not define variables in your header file.
If you absolutely must share variables between internal source files (and I recommend that you don't), then you should do the following:
Create an "internal.h".
Declare your variable extern in that header file.
Include "internal.h" in both your internal source files.
Define the variable in one or other internal source files.
The variable is now hidden from the outside world. (It's probably still visible in your object files, but you can use platform-specific trickery to strip it.)
Do not define variable in headers.
Use extern to declare a variable in a header without defining it.
I'm always weary about variables which are "on the loose". I mean: they do affect something don't they? They "belong" to a class?
Shouldn't you just declare them under a class, and then declare them as static variables? (And given the syntax, probably constants too)? In that case you can simply use everything normally done with static variables (initializer lists, static initialize function etc). Seems to me much more clearer, as now your variable is tied with something.
I have a header file that has a number of declarations like this:
extern ID3D10Device* device;
I can't make these static because of a problem with multiple translation units, and I can't have them as normal pointers for a similar reason. However when I try to build the program I get unresolved external symbol linker errors. I'm assuming that this is because I'm attempting to use the pointers without defining them first. This is the problem however, as the way you initialise these DirectX objects is by passing the address of the pointers as parameters into specialist methods. - I may be wrong but I am assuming this is the problem as the compiler / linker / whatever can't see the definitions.
All I'm trying to do is have these pointers (for the graphics device, depth buffer etc) visible to multiple classes. How can this be achieved?
You need the pointers to be defined in some translation unit. The linker is complaining because it seems you haven't done that anywhere. You should declare them at file scope as
ID3D10Device* device = NULL;
in the source file where you call the DirectX function that initializes them. Just make sure the declaration is only made in one source file, then the extern statement should be placed in the associated header file which is included by all translation units that need to use these pointers.
When you externally define a variable like this, the compiler is not reserving any memory for that variable until it sees a definition inside a code module itself. So if you are going to be passing these pointers by-reference to a function for initializing their values, they must be defined in a code module somewhere.
You only need to define them in a single code module ... then place the extern declarations inside a header file you include in the rest of your code modules that require access to the pointer variables. That shouldn't create any linker errors due to duplicate definitions.
I can't make these static because of a problem with multiple translation units
If you need a different variable in different TU (translation units), make it static: this way the variable will be specific to each TU.
A declaration of a variable is also definition unless the extern is used.
You must have one (and only one) definition of a variable in the program.
To have a global variable:
Declare it with the extern keyword in some header file.
Include this header in every TU that needs to use the variable. Never declare the variable directly, never bypass the header inclusion.
Define the variable: a declaration without the extern keyword will define the variable in one TU. You need to include the header file in the same TU to guaranty consistency between the extern declaration and the definition.
the way you initialise these DirectX objects is by passing the address
of the pointers as parameters into specialist methods
To solve this part of the problem, you could do something like this (in a .cpp file):
ID3D10Device* device;
struct Foo {
Foo(ID3D10Device **pdevice) { specialist_method(pdevice); }
};
Foo f(&device);
Beware of the "static initialization order fiasco", though -- it's safe to use device from main, or code called from main, because it will definitely be initialized before that code executes. It's not necessarily safe to use it from other initializers executed before main, because the order of initialization of statics in different translation units is unspecified (within a TU, they're initialized in order of either declaration or definition, I forget which). So device might still be a null pointer in that code. Likewise, specialist_method can't necessarily rely on other statics having been initialized.
There are extra tricks you can use if you need to enforce initialization orders, I'd guess that all the common ones are on SO already in other questions.
I have a number of C++ classes, alot of them (not all) share two "static size variables" e.g.
share.h
/*Other variables in this header used by all classes*/
static size width=10;//Used by about 60%
static size height = 12;//used by about 60%
So I placed them in a header file along with other objects that all classes share.
when I compile the project I get alot of warnings (from the classes which dont use these), which complain about them being defined and not used. But I need them there!
So I ask, is there a way to hash these to prevent such warnings?
Hashing them so that they can be defined! preventing warnings from classes calling this header file which dont require these last two variables, but they call header because they need everything else init
You should place them in an individual header file. So you can include it only in the classes they need it. This avoids the warning in the other classes. So in the end you will have two header files. One where the stuff for all classes is included and another where the variables which are not used in all are defined.
However try to avoid global variables.
Edit reading tune2fs' answer, I realized I may have interpreted the question wrong.
Perhaps you forgot to use extern in the header file? If you just include static definitions in the header file all compilation units will have unique copies, not shared. See also this explanation of static/extern
Edit Disambiguated in comments
static SomeClass NotUnusedInstance;
static void unused_vars_helper()
{
static SomeClass* take_address = &NotUnusedInstance;
}
This approach is design to have minimal impact (not invoking any actual code; take_address isn't actually initialized unless you call unused_vars_helper).
This should work pretty well for your case. You can make unused_vars_helper() static and/or move it inside an anonymous namespace to prevent external visibility of the helper.