header file include-loop and multiple definition - c++

I have a util.h containing a function which will be used in a.h and 'b.h', and further more, a.h and b.h will include each other in order to access some classes defined in each other.
//util.h
#ifndef _UTIL_H_
#define _UTIL_H_
#include <iostream>
void foo()
{
std::cout << "foo\n";
}
#endif
//a.h, it has a a.cpp
#ifndef _A_H_
#define _A_H_
#include "util.h"
#include "b.h"
//some classes' definition
#endif
//b.h, it has a b.cpp
#ifndef _B_H_
#define _B_H_
#include "util.h"
#include "a.h"
//some classes' definition
#endif
My problem is that, I got multiple definition error for foo. How?
I thought the problem might be that, a.h includes util.h and b.h, and b.h includes util.h once again, so I got multiple def error. But it can't seem to make sense, because in util.h I wrote #ifndef/#define guards.
Anyone can give me a help, thanks.

Your problem is caused by defining rather than simply declaring foo inside utils.h
For this example, assume that we have:
a.cpp
#include "a.h"
b.cpp
#include "b.h"
main.cpp
#include "a.h"
#include "b.h"
#include "utils.h"
int main(){
foo();
return 0;
}
After preprocessing, but before compilation, your files now look like this (this is a simplification, but you get the idea):
a.cpp
void foo()
{
std::cout << "foo\n";
}
b.cpp
void foo()
{
std::cout << "foo\n";
}
main.cpp
void foo()
{
std::cout << "foo\n";
}
int main(){
foo();
return 0;
}
Now when you compile, you have 3 definitions of foo (they're all identical, but this is irrelevant). After compilation, there is no way for the linker to know which definition to pick for any given call to foo and so it generates an error.
Instead of defining foo in the header, define it in utils.cpp and only put a declaration in utils.h, e.g.
utils.h
#ifndef _UTIL_H_
#define _UTIL_H_
void foo();
#endif
or, alternately, declare foo as static or inline:
utils.h
#ifndef _UTIL_H_
#define _UTIL_H_
static void foo()
{
std::cout << "foo\n";
}
/* OR */
inline void foo()
{
std::cout << "foo\n";
}
#endif
This is something you need to do only if you want to inline your function. In this case, the compiler needs a definition of the function in every translation unit where it is used, as it essentially becomes a compile-time macro.

Related

c++ - Undefined reference to <function name> when using multiple header files

I am new to C++ programming and I have been stucked in this for hours.
I have three header files: A.h, B.h and common.h and two .cpp files: A.cpp, B.cpp.
A.h
#ifndef A_H
#define A_H
#include"B.h"
class AA{
public:
void fun();
};
#endif
B.h
#ifndef B_H
#define B_H
#include <iostream>
#include "common.h"
using namespace std;
class BB{
public:
void fun2();
};
#endif
common.h
extern int c;
A.cpp
#include "A.h"
void AA::fun(){
cout<<"A"<<endl;
}
B.cpp
#include "B.h"
void BB::fun2(){
cout<<"FUN 2"<<endl;
}
main.cpp
#include "A.h"
int main(){
int c = 5;
AA a;
a.fun();
return 0;
}
Error: undefined reference to `AA::fun()'
Why am I getting this error? Can anyone explain it?
Thanks a lot.

C++ How to call a function from another file with the same name as a function in another file when both are included?

I am wondering how I could call a function from another file with the same name as a function in another file when both are included.
Example:
main.cpp
#include "a.h"
#include "b.h"
using namespace std;
int main()
{
start();
return 0;
}
a.h
#ifndef _A_H
#define _A_H
#pragma once
int start();
#endif
a.cpp
#include "stdafx.h"
using namespace std;
int start()
{
//code here
return 0;
}
b.h
#ifndef _B_H
#define _Win32_H
#pragma once
int start();
#endif
b.cpp
#include "stdafx.h"
using namespace std;
int start()
{
//code here
return 0;
}
the start(); in main.cpp will use start(); from a.h but I want it to use start(); from b.h
How do I do to select start(); in b.h?
Assuming that the functions are defined in the respective .cpp files, i.e., one is defined in a.cpp and one in b.cpp, then this cannot happen. Once you try to link your code, you will get the error that start() is defined twice. Therefore, you do not have to reason about how to call one of them; the code will not link anyway unless the two functions are the same (i.e. defined in the same cpp file). If this is the case, then it doesn't matter which one is called (as there is only one).

Include header files in c++

The C++ Premier I have doesn't say much about what I am about to ask, and this is what I got googling LINK:
When the compiler compiles the #include "example.h" line, it copies the contents of example.h into the current file.
So, if that's true, in the following example why B.h doesn't know about A.h ? Is it how the files are compiled ? Do I have to include A.h in every file that use it and then include every file that use A.h in the program.h that uses these files ?
In program.h
#include "A.h"
#include "B.h"
WARNING: VERY BAD CODE:
a.h
#ifndef A_H
#define A_H
#define SOME_LIT "string lit in A.h"
#endif
b.h
#ifndef B_H
#define B_H
#include <iostream>
void foo() { std::cout << SOME_LIT << '\n'; }
#endif
main.cpp
#include "a.h"
#include "b.h"
int main()
{
foo();
}
Prints:
$ ./a.out
string lit in A.h
So you can see b.h knows about the define in a.h. If you forgot the #include "a.h", or put it below #include "b.h", this would break.
As a general rule however, you should explicitly #include a header in any file you need it. That way you know that you only care about foo in main, so you just #include the foo header, which is b.h:
#include "b.h"
int main()
{
foo();
}

Multiple definition of a function error, even when using #if guard clauses

I am creating a simple UTIL.h file contain aplusb(int, int) function for my C++ project. However I cannot compile and the error message is about multiple definition of `aplusb(int, int)'. Would you please help me correct the error or give me some hints?
I attach here my project for your detail reference.
File UTIL.h
#ifndef UTIL_H_
#define UTIL_H_
int aplusb(int a, int b) {
return a + b;
}
#endif /* UTIL_H_ */
File ClassA.h
#ifndef CLASSA_H_
#define CLASSA_H_
class ClassA {
public:
ClassA();
virtual ~ClassA();
private:
int sum;
};
#endif /* CLASSA_H_ */
File ClassA.cpp
#include "ClassA.h"
#include "UTIL.h"
ClassA::ClassA() {
// TODO Auto-generated constructor stub
sum = aplusb(3,5);
}
ClassA::~ClassA() {
// TODO Auto-generated destructor stub
}
File ClassB.h
#ifndef CLASSB_H_
#define CLASSB_H_
class ClassB {
public:
ClassB();
virtual ~ClassB();
private:
int sum;
};
#endif /* CLASSB_H_ */
File ClassB.cpp
#include "ClassB.h"
#include "UTIL.h"
ClassB::ClassB() {
// TODO Auto-generated constructor stub
sum = aplusb(5,6);
}
ClassB::~ClassB() {
// TODO Auto-generated destructor stub
}
Compile error message
ClassB.o: In function `aplusb(int, int)':
/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: multiple definition of `aplusb(int, int)'
ClassA.o:/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: first defined here
collect2: error: ld returned 1 exit status
make: *** [commonfunc] Error 1
First variant - use inline specifier
#ifndef UTIL_H_
#define UTIL_H_
inline int aplusb(int a, int b) {
return a + b;
}
#endif /* UTIL_H_ */
Second variant - write definition in .cpp file.
You created the function aplusb in your include file. This means that for every file you include it to, a public function aplusb will be created, resulting in a name clash.
If the function should be inline, then mark it so. If the function should be a template, then mark it so. If the function should be as you wrote it, put it in a cpp file and just keep the protoype in the h file.
.h
#ifndef UTIL_H_
#define UTIL_H_
int aplusb(int a, int b);
#endif
.cpp
int aplusb(int a, int b)
{
return a+b;
}
You should declare your aplusb function in the header file, and provide the definition in a cpp file. Something like
util.h:
#ifndef UTIL_H_
#define UTIL_H_
int aplusb(int, int);
#endif /* UTIL_H_ */
The error message is telling you that each time that you include the util.h file, you are re-defining the function, which is exactly what you are doing :-) This is a violation of the ODR (one-definition-rule), which states that the definition (of a function, in this case) must be unique. Otherwise the compiler would be unable to choose between the alternatives (even if, like in this case, they happen to be equal).
Note that templates complicate the matter a bit (in short, because a template is not a definition until instatiated).
Header files are not intended to have actual functions in them (certain C++ aspects such as templates not withstanding). General practice in your case would have you changing your UTIL.H to just prototyping the function (int aplusb(int a, int b);) and moving its implementation to a source file.
You could also make a Util struct where every function is declared static. You can then access every function using Util::<function name>
File UTIL.h
#ifndef UTIL_H_
#define UTIL_H_
struct Util{
static int aplusb(int a, int b) {
return a + b;
}
};
#endif /* UTIL_H_ */
File ClassA.cpp
#include "ClassA.h"
#include "UTIL.h"
ClassA::ClassA() {
sum = Util::aplusb(3,5);
}
ClassA::~ClassA() {
}
File ClassB.cpp
#include "ClassB.h"
#include "UTIL.h"
ClassB::ClassB() {
sum = Util::aplusb(5,6);
}
ClassB::~ClassB() {
}

Cannot find a namespace despite it being RIGHT THERE

I have a namespace defined in one header file and used in another, but it cannot be found. Specifically, a namespace called "players" defined in "players/Players.hpp" and used in a file called "players/Ownable.hpp" cannot be found in a file called "combat/Targetable.hpp"
The errors are
...\source\combat\Targetable.hpp(7): 'players' : is not a class or namespace name
...\source\combat\Targetable.hpp(7): 'Ownable' : base class undefined
Obviously it's some syntax thing I don't understand. I've spent some time simplifying the code so it looks silly, but bear with me.
// source/players/Players.hpp:
#ifndef PLAYERS_HPP
#define PLAYERS_HPP
#include "../Headers.hpp"
namespace players {
class Player{
// this class compiles fine.
// There used to be a "Players.cpp" but it's been simplified away
public:
int getID(){ return 0; }
int getTeam(){ return 0; }
string getName(){ return ""; }
Vec3 getColor(){ return Vec3(0.0,0.0,0.0); }
};
}
#endif
And players/Ownable.hpp, which is in the same folder as Player.hpp and also compiles fine:
// source/players/Ownable.hpp:
#ifndef OWNABLE_HPP
#define OWNABLE_HPP
#include "Players.hpp"
namespace players {
class Ownable;
typedef boost::shared_ptr<Ownable> OwnablePTR;
typedef boost::weak_ptr<Ownable> OwnableWPTR;
class Ownable {
public:
Ownable(){}
Ownable(int playerID) : playerID(playerID){}
bool isAlliedWith(OwnablePTR other){ return false; }
private:
int playerID;
};
}
#endif
Here's where the fun starts. I have a file at "source/combat/Targetable.hpp", which is in a different directory than the other two. However, the file itself seems to include fine:
// source/combat/Targetable.hpp:
#ifndef TARGETABLE_HPP
#define TARGETABLE_HPP
#include "../players/Ownable.hpp"
namespace combat{
class Targetable : public players::Ownable { // ERROR
public:
Targetable(int playerID){}
//Targetable(players::Player player);
virtual Vec2 getPosition(){
return Vec2();
}
virtual Vec2 getVelocity(){
return Vec2();
}
};
}
#endif
I'm really hoping this is some silly syntax thing that I'm missing. I've even tried
using players::Ownable;
but that A) pollutes the files that include this one, and B) doesn't fix anything. Any help?
EDIT: GManNickG got it, it was a circular include in the Headers.hpp file. Thanks!
You have a circular include.
First consider the purpose of include guards:
// a.hpp
#ifndef A_HPP
#define A_HPP
// stuff
#endif
 
// b.hpp
#ifndef B_HPP
#define B_HPP
#include "a.hpp"
// stuff
#endif
 
// c.hpp
#ifndef C_HPP
#define C_HPP
#include "a.hpp"
#include "b.hpp"
// stuff
#endif
 
// x.cpp
#include "c.hpp"
The inclusion of c.hpp will end up include a.hpp twice. The first time, the guards are not defined and everything is okay, and the second time the guards prevent redefinitions. This is what we want.
This does not work when you have a loop, though. (It will prevent it, which is good, but it does "too well" because the guard is defined right after its tested, which means the contents of the header haven't actually yet been processed). Consider this instead:
// a.hpp
#ifndef A_HPP
#define A_HPP
#include "c.hpp"
// stuff
#endif
 
// b.hpp
#ifndef B_HPP
#define B_HPP
#include "a.hpp"
// stuff
#endif
 
// c.hpp
#ifndef C_HPP
#define C_HPP
#include "b.hpp"
// stuff
#endif
 
// x.cpp
#include "c.hpp"
Which is similar to what you have. x.cpp includes c.hpp, which is the first time it's been included so it defines C_HPP. Then c.hpp includes b.hpp, which includes a.hpp. Then a.hpp includes c.hpp and finds that C_HPP has already been defined, so the include does nothing.
Assuming a.hpp still manages to compile (that is, c.hpp isn't actually needed), then a.hpp finishes, then b.hpp finishes, then c.hpp finally actually defines its contents before returning to x.cpp.
The solution is to minimize the amount of headers you include. Use forward declarations, and most of all: do not use 'include everything' headers! These are terrible. And I suspect that's what Headers.hpp is.
How about class Targetable : public ::players::Ownable { . . .?
Note the global namespace qualification :: before players.