I am making a C++ project with the main.cpp which has main function, then a header file header.h and a cpp file program.cpp which has class methods in it. So I wanted to ask is there a way to declare a variable that i would use in main.cpp and methods could read it in program.cpp ?
Yes.
Look up the extern keyword in your C++ book.
Global variables are discouraged in general, but you can do this simply with the following in your header file:
extern my_global_type myGlobal;
you then define myGlobal in main.cpp as:
my_global_type myGlobal = \* some init value *\;
and simply use it in program.cpp by including the header with the above extern. You can make it a bit less global (but not get rid of all the problems) by putting myGlobal in a namespace.
Related
so i have 3 header file for classes
main.cpp includes global.h;global.h includes lifeform.h; lifeform.h includes item.h
i want to create an item and want to use it in global.cpp and main.cpp.i tried it like this
extern item IronSword("weapon","Iron Sword",200,10,40); in main.cpp or item.h or item.cpp but everytime compiler says [Warning] 'IronSword' initialized and declared 'extern' how can i use extern correctliy
You try to declare and define the object at the same time. In the header file just do e.g.
extern item IronSword; // Declare the variable IronSword
Then in one source file you have the definition:
item IronSword("weapon","Iron Sword",200,10,40); // Define the variable and initialize the object
I have this simple code in C++
#include <something.h>
#include <something2.h>
int main()
{
my_function();
return 0;
}
function with name my_function is defined in something.h and also in something2.h How to choose whichone I want to use without editting included files?
One solution is to use
namespace something_one
{
#include <something.h>
}
namespace something_two
{
#include <something2.h>
}
This works well if all the code is in the headers.
Otherwise you have to resort to #defines, stub functions implemented in carefully crafted compilation units, or a robust conversation with the global namespace polluter.
Assuming that actual definition resides in something.cpp (or .c) and something2.cpp (or .c),
Link only one of something.o or something2.o at the time of creating main application executable, depending upon from which file you want function to get executed.
With linking the correct file, you do not need to change any source code.
you might have to declare them as extern "C" at the point declaration and definition if you are compiling it as c++ files with g++ or gcc -std=c++0x or gcc -std=c++11.
I am wondering if it is possible to both declare and define an extern variable in the same header file. I need the variable to be referenced across multiple files, and while I realize there are better ways to achieve this, using extern is the only option in this case. So is it possible to do:
// in main.h
extern int foo;
int foo;
etc...
And then any file which includes main.h will have access to foo? Many examples reference defining the extern'd variable in a separate cpp file, but I'm just wondering if the way I suggested will cause problems across the rest of the project.
If you put a definition in a header file, you will end up with multiple definitions when multiple source files are involved.
For example, suppose both main.c and other.c include foo.h. When you compile each of these files you'll get main.o and other.o, both of which have a definition of int foo. If you then attempt to link main.o and other.o into a single executable, you'll get a linker error stating that int foo was defined twice.
To do this properly, you declare your variable in the header file as extern int foo. Then, in one (and only one) source file you define the variable with int foo.
Real definitions (not extern) should not be in a header file.
If you want to have one global variable available from different cpp, you should make two things: definition in one cpp and extern declaration in h.
E.g.:
// global.h
extern int foo;
and
// global.cpp
int foo;
Then in any file where foo is needed:
#include "global.h"
And, of course, global.cpp have to be part of project (compiled with other files)
What you are doing is perfectly legal in C++ only if there aren't multiple files which are defining the same variable.
The variable or function may be defined in another source file, or
later in the same file. Declarations of variables and functions at
file scope are external by default.
Normally we extern a global variable declared in some other file.
This is as good as a global variable initialized to 0.
*note: I am new to c++, so sorry if I make an obvious mistake.
I am getting an error on all of my variables. I am trying to use headers and forward declarations. Here is a snippet of my code:
//BotRenderer.h
#ifndef BOTRENDERER_H_
#define BOTRENDERER_H_
#include <SDL2/SDL.h>
SDL_Texture *botTextures[217];
int currentBotFrame;
//BotRenderer.cpp
#include "BotRenderer.h"
SDL_Texture *botTextures[217];
int currentBotFrame = 0;
All of the lines with variables give the error, '[variable name here] previously declared here'. What can I do to fix this?
The problem is that include guards only protect against multiple inclusion in the same translation unit (source file).
If you define a variable in a header file and include it in more than one source file then the variable will be defined in both source files (translation units), and when you then link the generated object files together the linker will notice that the variable is defined in both object files and give you an error.
What you should do is declare the variables in the header file, the easiest to do it is to add the extern keyword before the declaration, like
extern SDL_Texture *botTextures[217];
extern int currentBotFrame;
Regarding your compiler error, you get it just because you define the variables in both the header file and in the source file. The solution you your problem is the same, declare in header file and define in source file.
You should read about the One Definition Rule (a.k.a. ODR).
I have three files in my project.
a.c
b.c
test.h
test.h declares a
namespace test_namespace {
int i;
void f1();
};
test.h is also surrounded by
#ifndef __x
#define __x
...
#endif
now, a.c includes test.h and b.c also includes test.h .
a.c has the main() function, and b.c has the implementation of test_namespace::f1()
However, on compiling this, I get a linking error -
"test_namespace::i is already defined in <b.c's object file mapping in /tmp>"
If I've taken care to include conditional compilation preprocessor directives in test.h, why is it being included in both files a.c and b.c ?
Also is noteworthy that if I compile b.c separately as a shared library and then use it as a shared library while linking a.c's object file, i don't get this error.
Can someone please explain the above error to me, specially in the face of the conditional compilation directives ?
You cannot declare variables inside a headerfile.
The symbol test_namespace::i becomes exported by both a.c and b.c. The linker find's both and doesn't know which one to use.
What you want to do in test.h is:
namespace test_namespace {
extern int i;
void f1();
}
and then declare test_namespace::i in eather a.c or b.c:
namespace test_namespace {
int i;
}
Conditional inclusion is used to prevent headers from being included twice for the same source file not for the whole project. Suppose you have headersa.h and b.h, and b.h #includes a.h. Then if c.c needs things from both headers, it #include both of them. Since the C preprocessor using literal text substitution, when it includes b.h, there will now be two #include "a.h" directives in your file, wreaking the havoc of multiple declarations. (Edit: clarify why you run into problems in this case.)
Include guards are there to protect multiple header inclusions in the build of a compilation unit. They aren't necessary for cases when you have two separate code files and one header, like your example.
(So think more when test.c uses a.h and b.h, in those cases where b.h needs to #include a.h.)
But that's a note about what the include guard convention does and how it isn't buying you anything in this case. The specific technical issue you hit (as others have pointed out) is that you're basically defining the same variable in two different object files, and when the linker goes to pull everything together it doesn't know if you want the variable from a.o or b.o.
( Note: While compilers can generally be set to override things and build C++ code using features like namespace even if the extension is .c - you probably should be using something else, like .cpp: C++ code file extension? .cc vs .cpp )
You're defining test_namespace::i in the header. What you probably
want is extern int i; in the header, and a definition in one of the
source files.
What's happening is that when you say
int i;
this actually does two things:
1) Declares the symbol i
2) Reserves some space and a symbol for i in the object file
The trick is that (1) should only be done once per file (actually you can repeat it in this case) -- which is why you have the conditional include, which you have done correctly -- but (2) should only be done once per program
The solution is to have the header do
// Only declare -- don't create a symbol
extern int i;
And in the *.c file do
int i;
The header guards (#ifndef .. #define .. #endif) are working as they should. Both a.c and b.c include test.h, so they both get a copy of that header. (When you compile a program, what #include does is to literally copy-paste the contents of the header inside the source file.)
Since they both have a copy of the header, they both define the variable test_namespace::i. When the linker tries to link the code generated from a.c with the code generated from b.c it finds that they both define that variable. It doesn't know what to do, so it doesn't complete and outputs an error.