I recently tried to create a global header file which would have all definitions of error codes (i.e. NO_ERROR, SDL_SCREEN_FLIP_ERROR, etc.) these would just be integers which I would define here.
I included these in both of my .cpp files, however I am getting an error where it is stated that I am defining then twice.
globals.h:
#pragma once
// error related globals
int SCREEN_LOAD_ERROR = 1;
int NO_ERROR = 0;
main.cpp:
#include "globals.h"
#include "cTile.h"
/* rest of the code */
cTile.h:
#pragma once
#include "globals.h"
class cTile {
};
It is complaining that SCREEN_LOAD_ERROR and NO_ERROR are defined twice, but as far as I know #pragma once should prevent this (I also tried #ifndef, but this also did not work).
compiler output:
1>main.obj : error LNK2005: "int SCREEN_LOAD_ERROR" (?SCREEN_LOAD_ERROR##3HA) already defined in cTile.obj
1>main.obj : error LNK2005: "int NO_ERROR" (?NO_ERROR##3HA) already defined in cTile.obj
Am I missing something?
Do not declare variables inside your header file.
When you declare a variable in header file a copy of the variable gets created in each translation unit where you include the header file.
Solution is:
Declare them extern inside one of your header file and define them in exactly one of your cpp file.
globals.h:
extern int SCREEN_LOAD_ERROR;
extern int NO_ERROR;
globals.cpp:
#include "globals.h"
int SCREEN_LOAD_ERROR = 0;
int NO_ERROR = 0;
main.cpp:
#include "globals.h"
cTile.h:
#include "globals.h"
You could simply use an enum:
globals.h:
enum
{
SCREEN_LOAD_ERROR = 1,
NO_ERROR = 0,
// ...
}
using #ifndef works fine.(Although it works, this is not best practice). try like this:
globals.h
#ifndef GLOBALS
#define GLOBALS
int SCREEN_LOAD_ERROR = 1;
int NO_ERROR = 0;
#endif
cTile.h:
#include "globals.h"
class cTile {
};
main.cpp:
#include "globals.h"
#include "cTile.h"
/* rest of the code */
Related
I am getting LNK error 2005 due to the use of enum in header file. I am not sure what is wrong with it though. Is enum usually included in the header file?
Here is my code. I have 4 files: board.h, board.cpp, Solitaire.h, Solitaire.cpp.
board.h:
#ifndef BOARD_H__
#define BOARD_H__
#include <iostream>
using namespace std;
const int NUM_ROWS = 6;
const int NUM_COLS = 6;
enum PieceType {
HasPiece, NoPiece, Invalid
};
PieceType board_data[NUM_ROWS][NUM_COLS];
#endif
board.cpp:
#include "board.h"
Solitaire.h
#ifndef Solitaire_h__
#define Solitaire_h__
#include "board.h"
#endif
Solitaire.cpp
#include "Solitaire.h"
int main() {
}
The error I get is
Error LNK2005 "enum PieceType (* board_data)[6]"
(?board_data##3PAY05W4PieceType##A) already defined in board.obj
Thank you!
The problem has to do with including definitions in headers. This line
PieceType board_data[NUM_ROWS][NUM_COLS];
defines a new array board_data in each translation unit from which the header is included. To fix this issue, declare the array external, i.e.
extern PieceType board_data[NUM_ROWS][NUM_COLS];
After that, define the array in one of your CPP files.
Note: This problem is not about enum - you would get the same error with any other type.
I have declared a global variable in header.h and included that header in source.cpp and main.cpp but linker is giving error
Source.obj : error LNK2005: "int globalVariable" (?globalVariable##3HA) already defined in Main.obj
GlobalVariableAndLinkageIssue.exe fatal error LNK1169: one or more multiply defined symbols found
header.h
int globalVariable;
source.cpp
#include "header.h"
main.cpp
#include"header.h"
void main() {}
Move the declaration to a .cpp file. You can use a declaration in a header file by using:
extern int globalVariable; // declaration in header - can have as many as you need
But the .cpp file should have the definition:
int globalVariable; // definition in .cpp - only need one across all your files
C and C++ use textual pre-processor to include headers, this is basically a text insertion, not a smart module system as in some languages. By including it as you were, you are creating multiple definitions, one per .cpp file.
As a matter of good practice, you need to get used to using include guards to protect against multiple nested includes (though it would not solve your current issue). If using Visual C++, you can use #pragma once or to use a portable solution wrap your header code in:
#ifndef _INCLUDE_FOO_H_
#endif
To create a global variable, you should do the following. Note that in the header, we mark the variable as extern, and we actually create the object in a cpp file.
header.h
extern int globalVariable;
header.cpp
#include "header.h"
int globalVariable;
main.cpp
#include "header.h"
int main() {}
Put global variable in some .c or .cpp file, so that it can be defined only once and refer in header file using extern
for example,
header.h
extern int globalVariable;
header.cpp
int globalVariable = 0;
source.cpp
#include "header.h"
main.cpp
#include"header.h"
int main() {
return 0;
}
Because BOTH sources #include your header, and thus it is DEFINED twice.
In such situation,it is common to use some #define as follows:
//header.h
#ifdef DEFINE_VARS
#define DEFINE_OR_DECLARE
#else
#define DEFINE_OR_DECLARE extern
#endif
DEFINE_OR_DECLARE int globalVariable;
//main.cpp
#define DEFINE_VARS
#include "header.h"
...
//header.cpp
#include "header.h"
...
Below is my code:
MathCore.h
#ifndef __CC_MATHCORE_H__
#define __CC_MATHCORE_H__
#include "math.h"
class MathCore
{
public:
MathCore();
virtual ~MathCore( );
int x (int n );
};
#endif
MathCore.cpp
#ifndef __CC_MATHCORE_H__
#define __CC_MATHCORE_H__
#include "MathCore.h"
MathCore::MathCore()//a
{
}
MathCore::~ MathCore()//b
{
}
int MathCore::x (int n )//c
{
float v=0;
return v;
}
#endif
but it erports error at
a:C++ requires a type specifier for all declarations
Use of undeclared identifier 'MathCore'
b:Expected a class or namespace
c:Expected a class or namespace
Your comment welcome
You shouldn't have that #define in both the .cpp and .h files, as it will prevent the contents of the .h file from actually being included.
When you #include a file, for all practical purposes it behaves the same way as copying and pasting that file into wherever you have the #include. So, the first few lines of your MathCore.cpp are effectively this:
#ifndef __CC_MATHCORE_H__
#define __CC_MATHCORE_H__
#ifndef __CC_MATHCORE_H__
#define __CC_MATHCORE_H__
/* the rest of your .h file here */
When restructured that way, it becomes a little more obvious, that second #ifndef can never match since the symbol it's checking is defined immediately above.
Because, in your C++ file, you're using the same header guards as your header. The second line defines __CC_MATHCORE_H__. After this, you include the header, which does nothing if __CC_MATHCORE_H__ is defined. Remove the guard from the cpp file, and you'll be fine. Guards are rarely, if ever, needed in actual implementation files.
//////////////////////////////////MathCore.cpp
#include "MathCore.h"
MathCore::MathCore()//a
{
}
MathCore::~ MathCore()//b
{
}
int MathCore::x (int n )//c
{
float v=0;
return v;
}
Remove the include guard from MathCore.cpp
I've defined a struct in a header file global.h, that i try to use it in a another class, but i get this error : Error 6 error LNK2001: unresolved external symbol "struct tag_KG_Data g_GlobalVar" (?g_GlobalVar##3Utag_KG_Data##A) KGComThread.obj
#ifndef GLOBAL_H_
#define GLOBAL_H_
#include <stdio.h>
typedef struct tag_KG_Data
{
int nKGStationID;
int nKGComPort;
}GLOBAL_VAR;
#endif
and in KGComThread.cpp file i use it like this:
#include "global.h"
extern GLOBAL_VAR g_GlobalVar;
I think the compiler can't find the global.h file so it defines a meaningless tag_KG_Data struct, but i can't understand why.
This
extern GLOBAL_VAR g_GlobalVar;
is only a declaration. The variable is not yet defined:
GLOBAL_VAR g_GlobalVar;
You need the previous line in a single implementation file.
Also, since this is C++, you don't need a tag for the struct, you can just write
struct GLOBAL_VAR
{
int nKGStationID;
int nKGComPort;
};
I am trying to use a global variable from separated .cpp files. I have got an init.h file as:
//init.h
#ifndef init
#define init
int a = 3;
#endif
I have got an init.cpp file as:
//init.cpp
#include init.h
Then finally my main.cpp file is:
//main.cpp
#include "init.h"
int main(void)
{
while(1)
{
}
}
After this, I get the error:
1>init.obj : error LNK2005: "int a" (?a##3HA) already defined in main.obj
1> ..deneme.exe : fatal error LNK1169: one or more multiply defined symbols found
Why my #infdef control does not solve this problem?. I also tried using #pragma once but I got same error. What is wrong with my code?
You need to mark your variable as extern and define it only once in an implementation file.
As the code is now, you're breaking the one definition rule. The include guards don't help in this case, since all translation units that include that header re-define the variable.
What you actually need:
//init.h
#ifndef init
#define init
extern int a;
#endif
and the definition:
//init.cpp
#include "init.h"
int a = 3;
Also, think twice before using globals. What is it that you're actually trying to achieve?