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.
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 .
What is the proper way of declaring variables in the header file in c++? And if it is not a good idea, then why? Thank you.
The correct way would be to declare the variable with the extern keyword in the header file and then you have to declare it in one (!) cpp file without the extern keyword.
But:
Variables in header files are global variables. These have much problems. Here a few:
You don't know in which order they are initialized. When one is a class and their constructor accesses another global variable, it is possible that this other global variable isn't initialized
Global variables waste your namespace
When you use global variables, you almost certainly don't use well-known and proven programming concepts (like modularity). Also your functions will have many side effects which makes your code hard to understand. In a few weeks you will no longer know, which functions will change which variables, and so on. Your code will be much more readable and understandable, if you stick to this concepts and don't use global variables.
You should never use global variables in C++. They are only there for backward compatibility with C.
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.
this relates to a question i asked previously:
C++ array in header file
in the main.cpp file there is a variable called fin1
ifstream fin1("ACW2_data.txt");
this might be a stupid question, but how can i use the value of this variable from main.cpp in the header file? (ie. is there a way to pass variables between the two files?)
any other info about using header files may help
Thanks in advance
This variable can be declared in the header file as an extern.
extern ifstream fin1;
Now you can use this variable wherever you #include this header file including the header file itself. You don't need to pass the variable as such. :)
I think you need to back up and explain what you are trying to do. Header files are, in general, for defining common definitions and declarations.
What do you mean by "use the value in the header file"? In general, the header file is not where code is run. So what needs to use this variable there?
Generally speaking, variables that need to be used in more than one file should be declared in the header to begin with. In C++, this is normally in the form of class members.
Even more common is to pass variables as arguments when another function or method needs to use the same value.
I can't tell from the information you've provided, but it sounds like you're on the wrong track to me.
Declare this variable as extern .
extern ifstream fin1;
Than every time you change it it value gonna update and be ready in your header file
And you can include tour header every where and use that variable