Jump to content
  • Advertisement
Sign in to follow this  
finky45

does #ifndef work with ints n things??

This topic is 4233 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a global.h file where I define all my global things. Using #ifndef has worked for my function prototypes but when I try to add ints, bools etc, they get defined multiple times (for every time I include global.h)
#ifndef GLOBAL
#define GLOBAL

//VARIABLES
bool playerDead=false; //this gets defined multiple times... why?

//PROTOTYPES
bool fBattle(cPlayer*, cMonster*);
void fHome(cPlayer*, cTime*);
bool fCar(cPlayer*, cTime*);
void fDoc (cPlayer*, cTime*);
void fStore (cPlayer*);
void fTrain (cPlayer*);

//item declarations

//armor
//cArmor tshirt(10,1,10);

#endif




ERROR: cPlayer.o(.bss+0x0):cPlayer.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here cTime.o(.bss+0x0):cTime.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here fHome.o(.bss+0x0):fHome.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here fCar.o(.bss+0x0):fCar.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here fDoc.o(.bss+0x0):fDoc.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here fStore.o(.bss+0x0):fStore.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here cArmor.o(.bss+0x0):cArmor.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here cWeapon.o(.bss+0x0):cWeapon.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here fTrain.o(.bss+0x0):fTrain.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here cMonster.o(.bss+0x0):cMonster.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here fBattle.o(.bss+0x0):fBattle.cpp: multiple definition of `playerDead' life.o(.bss+0x0):life.cpp: first defined here EDIT: On second thought, would it even work? I would like to be able to access that playerDead bool from anywhere and set it to true if the player dies. Is there a way to do that without having to pass a pointer to it in each of my functions?

Share this post


Link to post
Share on other sites
Advertisement
Change the declaration in the header file to extern bool playerDead;, then put the actual definition bool playerDead = false; in one of the code files.

Also, I don't see the #endif at the end of your header -- it's worth checking that's there.

Share this post


Link to post
Share on other sites
Using the preprocessor to provide include guards (#ifndef/#define/#endif) only prevents multiple inclusion within a translation unit, not across them. You cannot define variables in a header file that will be included by multiple translation units, or you will get linker errors concerning multiple definitions of those variables; you cannot avoid this.

The most-direct solution is to define those variables in one translation unit (.cpp file, more or less); in the header, use the "extern" keyword in front of each definition. That will prevent the link errors.

A better solution is to avoid "global.h" style headers in general, because they can cause all sorts of nasty preprocessor oddness (especially if they #include other headers) that can result in errors that look fundamentally impossible.

They also increase coupling, dependencies, and compile times (changing them forces a recompile of every dependent file). They also encourage the bad practice of simply making everything you think you might need someplace global, allowing you to avoid actually thinking about a decent design.

Include and/or extern (if you must rely on globals for now) only the files that are needed. If you "need" every file to know about every variable, that is a sign of a bad, spaghetti-like design.

Share this post


Link to post
Share on other sites
"Header guards", as they're known, only work on one translation unit at a time. One translation unit is essentially the same as one .cpp file. Each .cpp file is compiled independently from all the others. Once all of these are compiled (usually into .obj files or something), they are linked. If any thing is found more than once (multiple definitions of a global, or of a function), the linker gets confused because it doesn't know which one to use.

The solution in your case is to do this in your header:
#ifndef GLOBAL
#define GLOBAL

//VARIABLES
extern bool playerDead;

#endif
and then put this in one, and only one, cpp file, perhaps global.cpp:
#include "global.h"

bool playerDead = false;
The extern keyword indicates to the compiler that there exists a variable called playerDead that is a bool. It doesn't know where it is, but it doesn't need to know. It only needs to know its existence. The linker will later come along and link all uses of the variable to its actual location, once it is known. But this location can only be one place. In the case above, it will exist in global.obj, and nowhere else. Any other cpp/obj file that uses playerDead will end up linking to the location in global.obj.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!