Xun Yang
Xun Yang

Reputation: 4419

Arduino library: multiple definitions of a function

Today I encountered a weird problem when trying to use IRremote library, and I managed to strip down the problem as following. If you have a folder in libraries, with Foo.h and Foo.cpp inside, and write a sketch to include Foo.h:

Foo.h

#ifndef Foo_H
#define Foo_H

int AAA() {
    return 0;
}

#endif

Foo.cpp

#include "Foo.h"

Sketch

#include <Foo.h>

void setup(){

}

void loop(){

}

The error message is:

 Foo\Foo.cpp.o: In function `AAA()':

 E:\workShop\Arduino\libraries\Foo\/Foo.h:5: multiple definition of `AAA()'

 includeTest.cpp.o:E:\workShop\Arduino\libraries\Foo/Foo.h:5:

 first defined here

I'm using a Windows 7 32-bit machine. Tested on Arduino 1.0.5, 1.0.4, and 21, 22.


So with some research I figured out the problem comes from my confusion of preprocessor and linking. This question explains how preprocessor includes file and include guard:

These are some of the pages helped me understand linking:

And this is a better explanation of inline specifier:

Upvotes: 8

Views: 22670

Answers (4)

Lucky Larry
Lucky Larry

Reputation: 39

It is a little more complicated than Bbrado's answer if the structure of your program is a little more complicated. You need to #include <Arduino.h> and #include the help file as shown here:

testCall.ino

#include "testCall.h"
void setup() {
  AAA();
}
void loop() {
}

testCall.cpp

#include "testCall.h"
beeHive AAA(void){
    beeHive a;
    a.bee = (byte)1;
    a.hive = (byte) 2;
    return a;
}

testCall.h

#include <Arduino.h>
struct beeHive {
  byte bee;
  byte hive;
};
beeHive AAA (void); //  prototype only

Upvotes: 0

Bbrado
Bbrado

Reputation: 71

Well, the distribution of stuff in your files is more than unusual to say the least.

Here is how it is commonly done:

Foo.h

#ifndef Foo_H
#define Foo_H

int AAA(void);  // Just the prototype, not the function body

#endif

Foo.cpp

#include "Foo.h"   // include the h file, although not strictly neecessary

// make the function and body
int AAA(void)
{
    return 0; 
}

Sketch.cpp

#include <Foo.h>  // include prototype, so the AAA function becomes known

void setup()
{
     ...
     AAA();   // call AAA somewhere
}

void loop(){

}

Upvotes: 6

juanchopanza
juanchopanza

Reputation: 227608

You define the function in the header, so you should use the inline keyword:

inline int AAA(){return 0;}
//               ^^^^^^^^^^ definition

Alternatively, place only the declaration in the header, and the definition in an implementation .cpp file, to be compiled.

Foo.h

#ifndef Foo_H
#define Foo_H

int AAA();

#endif

Foo.cpp

#include "Foo.h"

int AAA(){return 0;}

Upvotes: 1

Useless
Useless

Reputation: 67842

Well, you have defined the function in two places: once in Foo.cpp where it includes the header, and again in your sketch where it includes the header. C and C++ headers don't provide a module system, they're just literally pasted in place of the include statement.

Either declare AAA in the header, but define it in Foo.cpp (so there's only one definition), or mark it inline.

Upvotes: 13

Related Questions