Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

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
like image 604
tamvo Avatar asked May 06 '13 09:05

tamvo


3 Answers

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.

like image 130
ForEveR Avatar answered Nov 09 '22 23:11

ForEveR


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;
}
like image 31
Devolus Avatar answered Nov 09 '22 22:11

Devolus


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).

like image 43
Francesco Avatar answered Nov 10 '22 00:11

Francesco