I want to run a small simulation in c++.
To keep everything nice and readable I seperate each thing (like all the sdl stuff, all the main sim stuff, ...) into it's own .h file.
I have some variables that I want all files to know, but when I #include them in more then one file other the g++ compliler sees it as a redefinition.
I understand why he does this, but this still leaves me with my wish to have one file where all important variables and constants for each run are defined and known to all other files, to easily find and change them when running my simulation.
So my Question here: Is there a good workaround to achieve that or something similar?
You can put the declarations for all the globals in a header and then define them in a source file and then you will be able to use those global variables in any other source file by just including the header as shown below:
header.h
#ifndef MYHEADER_H
#define MYHEADER_H
//declaration for all the global variables
extern int i;
extern double p;
#endif
source.cpp
#include "header.h"
//definitions for all the globals declared inside header.h
int i = 0;
double p = 34;
main.cpp
#include <iostream>
#include "header.h" //include the header to use globals
int main()
{
std::cout << i <<std::endl;//prints 0
std::cout<< p << std::endl;//prints 34
return 0;
}
Working demo
Mark them as extern in the header and have one translation unit that defines them.
Note: Without LTO (link time optimization) this will seriously slow down your simulation.
Related
I need to edit and access a few variables across multiple cpp files in a visual studio project. So I created a header file with a namespace containing all the variables I require as follows:
namespace windowdimension{
TCHAR openwindows[20][180];
int winnum = 0;
int windowleft = 0;
int windowright = 1360;
INT windowtop = 0;
INT windowbottom = 768;
LONG leftarray[20];
LONG rightarray[20];
LONG toparray[20];
LONG bottomarray[20];
}
However if I #include this header file in two source files, I get this linker error 2005 saying the parameter was already defined in the other obj.
On referring to other question of the same error, I got to know here that
a function definition can only appear once. Every .cpp file that #includes your .h file will generate yet another copy of the function.
But does that hold for namespace variables as well?
If so how do we ensure access to a particular variable across multiple source files?
You should never define global variables in a header file.
To be able to share, you need to declare them in a header file (using extern keyword), and define only once in a .cpp file.
Sure, never forget about include guards in every header file (#pragma once is pretty portable solution):
global.hpp
#pragma once
namespace global {
extern int variable;
}
global.cpp
namespace global {
int variable = 0;
}
Anyway, it is a very bad practice to use global variables.
You probably forgot to add an include guard:
Header.h
#ifndef HEADER_H
#define HEADER_H
namespace something {
}
#endif
Another option is to use #pragma once in the very beginning of your header file.
Note: The question has already been answered here undirectly
The problem is not include guards : they won't help across different
translation units
Note: I know the solution is to use extern keyword.
I'm new to C++. I have a problem understanding #ifndef in header files. When I do something like this, I get an error saying that the variables game_over and turn are already defined.
/*chess.h*/
#ifndef CHESS
#define CHESS
#include <iostream>
#include "chessboard.h"
using namespace std;
bool game_over;
char turn;
chessboard board;
int main();
#endif
/*bishop.cpp*/
#include "bishop.h"
#include "chess.h"
bishop::bishop(string pos, char color)
{
int x = pos[0] - 97;
int y = pos[1] - 1;
name = "bishop";
this->color = color;
board.add_new(*this);
}
/*chess.cpp*/
#include "chess.h"
int main()
{
...
}
Why are the variables defined twice in here? I thought that first time when chess.h is included, CHESS is defined. So in bishop.cpp, #include "chess.h" will not do anything since the header will skip to #endif from #ifndef CHESS. But it does not work like that obviously. Why am I wrong?
The #ifndef only blocks the code if the symbol is defined within the same translation unit, at a point before the #ifndef. A translation unit is a source file (.cpp) and all the files that are included into it. Since you're compiling two source files, they'll both have a complete include of the .h file.
You already appear to know how to handle the problem of defining global variables in a header file: declare them extern in the header, and put a definition into one of the sources. I would be remiss though if I didn't warn you to avoid globals in the first place, as your programs grow they'll make your life difficult.
I'm using Xcode to build a C++ project.
But I don't understand the error message:
"Apple Mach-O linker command failed with exit code 1"
I found that #include is the reason.
I have two .cpp file which include a same .h file. If I remove #include of one, it will be build successfully.
Other header files are fine expect the header file described above. I already used "ifndef".
#ifndef include guards only work at the level of the translation unit (usually a single source file).
If you define the same object twice in two translation units, that won't be fixed by include guards but the linker will complain bitterly when you try to combine the two object files into a single executable.
I suspect your situation is akin to:
hdr.h:
#ifndef HDR_H
#define HDR_H
void rc(void);
int xyzzy;
#endif
prog1.c:
#include "hdr.h"
#include "hdr.h"
int main (void) { rc(); return xyzzy; }
prog2.c:
#include "hdr.h"
void rc(void) { xyzzy = 0; }
In a situation like that, the include guard will prevent the header being included twice in prog1.c but it will still be included in both prog1.c and prog2.c, meaning that each will have a copy of xyzzy.
When you link them together, the linker will not like that.
The solution is to not define things in headers but to merely declare them there, leaving the definition for a C file:
hdr.h:
#ifndef HDR_H
#define HDR_H
int rc(void);
extern int xyzzy; // declare, not define
#endif
prog1.c:
#include "hdr.h"
#include "hdr.h"
int main (void) { rc(); return xyzzy; }
prog2.c:
#include "hdr.h"
int xyzzy; // define
int rc(void) { xyzzy = 0; }
Declarations are things like function prototypes, extern variables, typedefs and so on (simplistically, things that declare something exists without actually creating an "object").
Definition are things that create "objects", like non-extern variables and so on.
You need to track down what "object" is being defined twice (the linker output should have something like doubly-defined symbol 'xyzzy') and then make sure it's not defined in the header.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does this not prevent multiple function declarations?
Global.h
#ifndef Global_h
#define Global_h
#include <iostream>
unsigned char exitStatus;
#endif
OutputHandler.h
#ifndef OutputHandler_h
#define OutputHandler_h
#include "Global.h"
class OutputHandler {
private:
static bool instanceExists;
// more code
#endif
Root.h
#ifndef Root_h
#define Root_h
// declarations
OutputHandler *output;
#endif
Root.cpp
#include "Root.h"
// gets instance of OutputHandler
// more code
I am getting errors regarding exitStatus, static bool instanceExists, and static class output being already defined by Root.obj in OutputHandler.obj. I assume the issue is with including the header file OutputHandler.h in both Root.h and OutputHandler.cpp. Anyone know how to fix this or how to better organize header files?
Because include guards only work at the translation unit level (you can, for this simple case, consider a single C file to be a translation unit).
That means a single C file, if it includes the header file twice, will not process it the second time due to the include guards.
However, if you include the header from two different C files, each of them will get a copy of the variables defined in that header.
Then, when you link them together, you get the duplicates.
The easiest way to get around this problem is to never define things in headers, only declare them.
So, in the header (eg, xyzzy.h), you have:
extern int xyzzy; // declare but don't define.
and in all the C files that want to use that, put:
$include "xyzzy.h"
and, in one of those C files, also put:
int xyzzy; // define it here, once.
You can think of declaration as a simple "I declare that this exists somewhere, just not here", while definition is "I an creating this here and now".
Declare extern usigned char exitStatus in Global.h and define it in one implementation file.
The problem is during the linking phase; include guards in the headers won't help you.
In C, there is the separate concepts of declarations and definitions. Declarations are what are put into headers; they merely state that a particular variable exists. The definition of a variable is where storage is actually allocated for it.
For example, in your Global.h, you have:
#ifndef Global_h
#define Global_h
#include <iostream>
usigned char exitStatus;
#endif
This is defining a variable called exitStatus, and the linker is complaining because any given variable should only be defined in one place in a program. What you need to do is declare it in the header, and then define it in only one place in a source (*.cpp) file. For example, your header should declare exitStatus with:
extern char exitStatus;
and in only one source file, define it with:
char exitStatus;
The situation is similar for output in Root.h, as well as any other place you should be declaring variables in the header file.
See also: http://www.cprogramming.com/declare_vs_define.html
I began to write my program in a single cpp-file but now I have too much code so I decided to separate it. But the problem is that I have many constants, includes and some other things that I want to have all in one place. Unfortunately, all of them are needed by dependent parts of code so I can't do it with usual include files.
What would help me?
(I write under Linux and compile with command-line)
(Sorry for my English :))
As Hristo said, you should generally write the definitions in header files and write the implementation in the source code files.
To answer your question however:
But the problem is that I have many constants, includes and some other things that I want to have all in one place.
What I've typically done is create a single file called something like "common.h" or "defs.h" (I took the idea from Doom...) and that file has many defines that you find you need throughout your entire program. If you are using constants, declare the constants in the header file like so:
extern const int MAX_SOMETHING;
extern const bool TRUTH_VALUE;
and make a complementary source file (defs.cpp or common.cpp) that defines these constants:
const int MAX_SOMETHING = 5;
const bool TRUTH_VALUE = true;
so now when you include the common/defs.h in other source files, the extern keyword will tell that source file that the definition is in another source file (its in the common/defs.cpp) so it will find the definition in there, and you can use it anywhere where you have included common/defs.cpp.
In most projects definitions are in header files and implementations are in source code files. However the implementations of template functions must be in the header files because they must be visible to all source files using them. Variables should be defined extern in header files and be declared in source files. Constants may also be declared in header files static.
Example:
Foo.h
#pragma once
class Foo{
public:
void bar();
template<class Type>
void increment(Type &a){
++a;
return;
}
};
extern Foo theFoo;
static const int five=5;
Foo.cpp
#include "Foo.h"
#include <iostream>
void Foo::bar(){
std::cout<<"Foo::bar called"<<std::endl;
return;
}
Foo theFoo;
Main.cpp
#include "Foo.h"
#include <iostream>
int main(){
theFoo.bar();
std::cout<<five<<std::endl;
return 0;
}