Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Nov 13th, 2005, 9:22 AM   #1
some1
Programmer
 
Join Date: Dec 2004
Posts: 50
Rep Power: 4 some1 is on a distinguished road
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;

#endif

I also tried using "#pragma once" but nothing changes.

Here is the build output

Quote:
Originally Posted by Build output
Compiling...
code2.cpp
Including globals.h
main.cpp
c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\useoldio.h(29) : warning C4995: '_OLD_IOSTREAMS_ARE_DEPRECATED': name was marked as #pragma deprecated
Including globals.h
Generating Code...
Linking...
code2.obj : error LNK2005: "int x" (?x@@3HA) already defined in main.obj
Debug/InclusionGuards.exe : fatal error LNK1169: one or more multiply defined symbols found
Note that the "Including Globals.h" message appears twice.

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
some1 is offline   Reply With Quote
Old Nov 13th, 2005, 10:39 AM   #2
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
This generates code. Don't do that in your header files or you'll (obviously) get multiple definitions.
int x = 0;
There are infrequent exceptions to that rule, but you haven't hit them. Go with a declaration and initialize it elsewhere.

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
DaWei is offline   Reply With Quote
Old Nov 13th, 2005, 11:24 AM   #3
some1
Programmer
 
Join Date: Dec 2004
Posts: 50
Rep Power: 4 some1 is on a distinguished road
DaWei thanks for your reply.

I replaced the "int x = 0;" with just "int x;" but I still get the same linking error .
some1 is offline   Reply With Quote
Old Nov 13th, 2005, 11:34 AM   #4
Ras Qulec
Newbie
 
Join Date: Sep 2005
Posts: 10
Rep Power: 0 Ras Qulec is on a distinguished road
Try making the header file have extern int x; and put int x=0; in one of the source files as a global.
Ras Qulec is offline   Reply With Quote
Old Nov 13th, 2005, 11:35 AM   #5
OpenLoop
Expert Programmer
 
OpenLoop's Avatar
 
Join Date: May 2005
Location: East Lansing, MI
Posts: 663
Rep Power: 4 OpenLoop is on a distinguished road
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.
OpenLoop is offline   Reply With Quote
Old Nov 13th, 2005, 11:35 AM   #6
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
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
DaWei is offline   Reply With Quote
Old Nov 13th, 2005, 11:44 AM   #7
lectricpharaoh
Caffeinated Neural Net
 
lectricpharaoh's Avatar
 
Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 927
Rep Power: 4 lectricpharaoh will become famous soon enough
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;
And use this in your header file:
extern long count; 
extern int errorCode;
The reason you do it like this is to a) avoid multiple definitions of the same symbol within the same scope, and b) allow you to compile your source file that defines these variables into an object file (possibly adding it to a library), and use it without receiving 'undefined symbol' errors.

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
lectricpharaoh is offline   Reply With Quote
Old Nov 14th, 2005, 1:01 PM   #8
some1
Programmer
 
Join Date: Dec 2004
Posts: 50
Rep Power: 4 some1 is on a distinguished road
Quote:
Originally Posted by DaWei
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".
This is just a test app. I am building an application with many windows and I have an array of HWND vars to hold their handles and I want the array to be global so I can access it anywhere from the application (each window is like a small application so I have different .cpp and .h files for each).

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.
some1 is offline   Reply With Quote
Old Nov 14th, 2005, 3:15 PM   #9
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
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
DaWei is offline   Reply With Quote
Old Nov 27th, 2005, 9:19 AM   #10
some1
Programmer
 
Join Date: Dec 2004
Posts: 50
Rep Power: 4 some1 is on a distinguished road
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""
some1 is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 6:57 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC