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
Related
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 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.
Say I have a header file to store an enum:
my_enum.h:
#ifndef my_enum_h
#define my_enum_h
enum my_enum {ONE, TWO};
#endif
Then I include this header file in the files game.h and game.cc. Finally, I include game.h in main.cc.
I can now use ONE and TWO in main.cc. Is it normal to have these variables globally defined?
When you include game.h in main.cc, because game.h already includes my_enum.h, it can be accessed from files who include game.h, aswell as including my_enum.h
Solution 1:
Remove "#include my_enum.h" from your code, as it doesn't seem as if it needed
Solution 2:
Maybe change the name of the enum/the values inside
If you include a header in your implementation file. It is the same as writing the exact code of header file in your implementation file.
Hence this enum declaration gets included in your game.h and subsequently in your main.cc.
If you want to remove it, you will have to remove it from the header file and declare it locally wherever you want to use it.
In an .h file, I am declaring a global variable as:
#pragma data_seg(".shared")
#ifndef DEF_VARX
#define DEF_VARX
int VARX=0;
#endif /*DEF_VARX*/
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
However if I include this file in multiple cpp files, when I try to compile, I get " error LNK2005: "int VARX" (?VARX##3HA) already defined in Dll.obj" error. If I include in only one cpp file, no problem is encountered.
Isn't #IFNDEF.... check enough for preventing this? Am I missin something?
The reason of this behavior is, that you compile the line
int VARX=0;
into each .obj file. Thats OK for compiling, but upon linking the symbol becomes multiply defined, which is illegal. Using
extern int VARX;
in the header file, and
int VARX=0;
in one (and only one) source file resolves this problem.
I think you're supposed to forward declare the variable in the .h and later define it in its shared section in a .cpp, something like:
// in a header file
#pragma once
extern int VARX;
// in a .cpp
#pragma data_seg(".shared")
int VARX=0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
The problem is that is that you prevent multiple inclusion of the file for a given translation unit. (for a given say cpp file)
But if several of your cpp include this VARX.H, then you'll have more than one definition for this variable.
Instead, you should only declare the variable in the .H file, but initialize it to 0 in only one location.
Yes, you're missing the extern keyword.
In your header file, use:
extern int VARX;
In a source file, actually declare space for the variable:
int VARX = 0;
ifdef prevents it for a separe object file. When the header is include in several source (cpp) files, VARX will be dedfined in all of them. Consider declaring it as extern in header file, and initialize in one cpp file.
The problem is you must be including the file in multiple compilation units. Let's say you have a.cpp and b.cpp. Both include your header file. So the compiler will compile (and pre-process) separately, so for both files, DEF_VARX is not yet defined. When you go to link the to object files together, the linker notices that there is a name collision.
As others have suggested, the solution would be to declare it 'extern', then place the actual value in a cpp file, so it only is compiled once, and linked to everything without name collisions.