![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 | |
|
Programmer
Join Date: Dec 2004
Posts: 50
Rep Power: 4
![]() |
Including files and inclusion guards
Hello everyone!
I've been having this annoying problem for a while and I cant sort it out. I have file "globals.h" where I store all my global vars in. I also have 2 other files main.cpp and code2.cpp where I write my code. The problem is, when I #include "Globals.h" in both main.cpp and code2.cpp it gives me this error: fatal error LNK1169: one or more multiply defined symbols found So I tried using inclusion guards like this: #ifndef _INC_GLOBALS #define _INC_GLOBALS ....variable definitions here..... #endif but it keeps giving me the same error. if I remove the #include "Globals.h" from one of the files it just says that variable x is not defined. I used #pragma message to see how many times the linker uses the file and it outputs my msg twice. So here is a sample application I built just to test this: Main.cpp #include <iostream.h>
#include "globals.h"
int main(int argc, char *argv[])
{
x = 123;
return 0;
}code2.php #include "globals.h"
void DoSomething();
void DoSomething()
{
x = 456;
}Globals.h #ifndef _INC_GLOBALS
#define _INC_GLOBALS
#pragma message("Including globals.h")
int x = 0;
#endifI also tried using "#pragma once" but nothing changes. Here is the build output Quote:
I also dont understand why, when even if I include e.g. windows.h or iostream.h 100 times in the same file I never get such errors while they use the same inclusion guard method... In desperate need of help, Some1 ![]() |
|
|
|
|
|
|
#2 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
This generates code. Don't do that in your header files or you'll (obviously) get multiple definitions.
int x = 0; Globals aren't evil. They are VERY, VERY OFTEN misused, and a source of headaches and bugs. Without even looking, I'll guess you have too many and can do it more robustly. Header guards are to prevent the inclusion of a header file more than once in the SAME source file. They don't do diddly squat in regard to multiple source files.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#3 |
|
Programmer
Join Date: Dec 2004
Posts: 50
Rep Power: 4
![]() |
DaWei thanks for your reply.
I replaced the "int x = 0;" with just "int x;" but I still get the same linking error . |
|
|
|
|
|
#4 |
|
Newbie
Join Date: Sep 2005
Posts: 10
Rep Power: 0
![]() |
Try making the header file have extern int x; and put int x=0; in one of the source files as a global.
|
|
|
|
|
|
#5 |
|
Expert Programmer
Join Date: May 2005
Location: East Lansing, MI
Posts: 663
Rep Power: 4
![]() |
The #ifndef will only work at compile time in the same file or in other included files, but linked files are a different issue. You compiled main which included Globals.h. Then you seperatly compiled code2.cpp which also included Globals because as far as the compiler's concerned, main and code2 are two seperate files that do not include each other. However, at linkage time, you have two object files with the definition of int x in each one thus generating the error of duplicate definition.
|
|
|
|
|
|
#6 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Declare it external in the header and put the Real Thang in one source file. Why are you doing this? Practice? One rarely needs a global variable, particularly one named, "x".
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#7 |
|
Caffeinated Neural Net
Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 927
Rep Power: 4
![]() |
Rather than defining your variables in your header, define them in a C or C++ source file, outside of all functions. You can initialize them in this file. Do not declare them with the static keyword, as this will limit their visibility to this single source file. Then, in your header file, simply declare them, using the extern keyword. This tells the compiler that the variables are defined elsewhere, but allows the declaration to be in scope so you don't get an undefined symbol error.
To paraphrase, use this in your source file: long count = 0; int errorCode = 0; extern long count; extern int errorCode; The trick here is to realize the difference between a 'definition' and a 'declaration'. A declaration merely declares something, so the compiler knows of its existence and what type it is. This applies to functions as well as variables. For example, a prototype is a declaration. The sole purpose of this is to allow the compiler to perform proper error checking (such as issuing a warning or error when you assign a long to a short, or call a function with the incorrect number or type of arguments) and possibly some optimizations (the more information the compiler has, the better it can do its job). A definition, on the other hand, actually creates an instance and allocates storage (for variables) or contains the code body (for functions). Note that a definition is essentially a stronger form of a declaration; in other words, every definition is a declaration as well, but not every declaration is a definition.
__________________
A man's knowledge is like an expanding sphere, the surface corresponding to the boundary between the known and the unknown. As the sphere grows, so does its surface; the more a man learns, the more he realizes how much he does not know. Hence, the most ignorant man thinks he knows it all. - L. Sprague de Camp |
|
|
|
|
|
#8 | |
|
Programmer
Join Date: Dec 2004
Posts: 50
Rep Power: 4
![]() |
Quote:
I also have a char array which holds the application name so I can use it in MessageBox() calls throughout my app. I dont really know which is the right way to do it. |
|
|
|
|
|
|
#9 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
This shows where you will place the global declarations/definitions. Then proceed according to lectric's explanation.
#include <myheaderfiles.>
This area, where you might find other preprocessing commands,
is where you declare "global" variables.
int myGlobal int;
char myGlobalString [] = "My Global String";
int main (int argc, char *argv [])
{
// Once you're in here, you're in
// "local" territory, with declarations.
// However, you may INITIALIZE globals here.
...
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#10 |
|
Programmer
Join Date: Dec 2004
Posts: 50
Rep Power: 4
![]() |
Ok, so I've done that and everything works, thx everyone.
Now I have another problem, I'm trying to create a global pointer to a custom class in the global.h like this extern MYCLASS *pMyClass; but I get yet another linking error: "error LNK2001: unresolved external symbol "class MYCLASS * pMyClass"" |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|