Arduino library: multiple definitions of a function - c++

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:
In C++ why have header files and cpp files?
These are some of the pages helped me understand linking:
1.8 — Programs with multiple files
GCC and Make - A Tutorial on how to compile, link and build C/C++ applications
Guide: Multiple sources
And this is a better explanation of inline specifier:
inline specifier

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.

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(){
}

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;}

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

Related

Undefined reference to class member function when using more than 1 source file

I'm trying to learn how to seperate header and implementation files but it is not working even though i tried to keep it as simple as possible
header file
// foo.h
#ifndef FOO_H
#define FOO_H
struct Foo{
void bar();
};
#endif
implementation file
// foo.cpp
#include "foo.h"
#include <iostream>
void Foo::bar(){
std::cout << "test";
}
main file
// test.cpp
#include <iostream>
#include "foo.h"
int main(){
Foo foo;
foo.bar();
}
when i try to compile this, it throws an error
test.cpp:(.text+0x15): undefined reference to `Foo::bar()'
In order to compile multiple files, you would add both .cpp files to your project under the same target. Then your DEV C++ IDE will automatically add both files to the build and link them together.
On the completely, different note, Please avoid using DEV C++, it is very very old and hasn't seen updates in years. I'd recommend CodeBlocks instead.
You didn't tell us how you're compiling your code, but you need to compile foo.cpp in addition to test.cpp. If you're using GCC, the command is:
g++ test.cpp foo.cpp -o test
You forgot to add void in the definition of bar (in implentation file).
It should be void Foo::bar() {....

Linker error when including header in files other than main.cpp

I'm trying to add some utility functions and global variables to my code in such a way that I can be able to use them in every class I want in my project. I would like to use a .hpp file for the definitions end a .cpp file for the implementation.
This is a summary of these two files:
// This is Utilities.hpp
#ifndef utilities_hpp
#define utilities_hpp
namespace utils {
int global_variable1;
int global_variable2;
void utility_function1(...);
void utility_function2(...);
void utility_function3(...);
}
#endif /* utilities_hpp */
and the implementation:
// This is Utilities.cpp
#include "Utilities.hpp"
namespace utils {
void utility_function1(...) {
// Some code
}
void utility_function2(...) {
// Some code
}
void utility_function3(...) {
// Some code
}
}
Other than my main.cpp file I have two other classes. My main.cpp file includes Class1.hpp header that includes Class2.hpp header.
Now I thought that I could put another #include "Utilities.hpp" in Class1.hpp or Class2.hpp without any problems since I've used the guards in that header. The thing is that when I try to do that the linker throws me this error: Apple Mach-O Linker (ld) Error Group - clang: error: linker command failed with exit code 1 (use -v to see invocation) and I can't understand why or what to do to solve it.
I'm using Xcode 8.3 on a macOS Sierra 10.12.4.
I hope I was able to explain my problem, thank you all very much in advance.
You've violated the One Definition Rule. global_variable1 and global_variable2 should be declared extern in your header and defined in exactly one translation unit (probably Utilities.cpp).
You've defined global variables in a header that gets included in multiple translation units, so there's a utils::global_variable1 defined in main.cpp, and one in Utilities.cpp. When it comes to link time, the linker has no way to know which global_variable1 to use, so it throws an error.
To fix it, add the extern keyword to your declarations and add a definition in "Utilities.cpp":
Utilities.hpp:
// This is Utilities.hpp
#ifndef utilities_hpp
#define utilities_hpp
namespace utils {
extern int global_variable1;
//^^^^^^ <-----HERE
extern int global_variable2;
//^^^^^^ <-----HERE
void utility_function1(...);
void utility_function2(...);
void utility_function3(...);
}
#endif /* utilities_hpp */
Utilities.cpp:
// This is Utilities.cpp
#include "Utilities.hpp"
namespace utils {
int global_variable1; //<---- Definitions added
int global_variable2;
void utility_function1(...) {
// Some code
}
void utility_function2(...) {
// Some code
}
void utility_function3(...) {
// Some code
}
}
You're missing the extern keyword on your global variables in your header. As a result, you're defining them, which results in multiple definitions when you include the header in two different source modules.
Once you add the extern in the header file (extern int global_variable1;), you'll need to add the definition in your .cpp file where you also define your functions.

When to include foo.h in foo.cpp

I have frequently seen people #include "foo.h" at the top of "foo.cpp". It looks like you could always do this, but people don't. So there must be some reason behind the choice.
When should I #include the header (foo.h) inside the source file (foo.cpp)?
The reason to put it at the top is simply to check that its contents don't depend on any other headers. For example:
// foo.h
void f(std::vector<int>& v);
// foo.cpp
#include <vector>
#include "foo.h"
// foo1.cpp
#include "foo.h"
#include <vector>
In foo.cpp, there's no problem: everything compiles just fine. foo1.cpp, on the other hand, won't compile, because foo.h uses std::vector without an include directive.
Having every header file compilable on its own avoids mysterious failures that otherwise occur when you change include directives in a file that has nothing to do with foo.cpp. These are sometimes hard to identify, and they're always frustrating.
You need to include the header if you're using anything inside the header.
For example, if you need to create foo someObject = new foo(); in your main method, you need to include the header foo.hthat has that class definition.
You only need to include things that you know you're going to use.
You can include a header file whenever you want.
Anyway, suppose you have a file main.h similar to the following one:
#ifndef FOO_H
#define FOO_H
struct S { };
#endif
Now, this main.cpp works just fine, as you mentioned:
void f() { }
#include "foo.h"
int main() { f(); }
Anyway, if I slightly change the main.cpp it doesn't work anymore:
void f() { S s{}; }
#include "foo.h"
int main() { f(); }
The problem is that S is declared after its first use and it is not visible when the definition of f is encountered for the first time.
So, the rule of thumb could be - include a header immediately before you start using something (let me say) imported by that file.
Anyway, this could quickly lead to messy files with #include directives spread all around and a common practice is to simply put all of them at the top of the file and that's all.

C++ I have a function used in all my headers

I have a function that is the same across all my header files and main.cpp if I define it in main.cpp will they all be able to use it once they are included or will they have a compiler issue?
Still new to this whole header file business. Thanks in advance.
In the header file (myfunction.h), you need to have only declaration of the function:
int foo(int param);
In the main.cpp (or any other cpp file - better choice would be myfunction.cpp - just make sure definition is included in exactly one file!) file, you need to have definition of the function:
int foo(int param)
{
return 1;
}
In all other source (cpp) files where you're using function foo, just include myfunction.h and use function:
#include "myfunction.h"
void someotherfunction()
{
std::cout << foo(1) << std::endl;
}
Compiler only needs to see declaration of the function before it is used. Linker will connect definition of the function with the places you've used the function. If you forget to write definition in main.cpp file, you will not get compiler, but a linker error. It may be worth of mentioning that compiler is compiling each cpp file separately, and linker's job is to combine all compiler object files and to produce final output file. On most setups, linker will be called automatically after compiling, so you may not be familiar with it.
If you include entire function definition in the header file, that definition will be compiled in each translation unit where header file is included, and you will get multiple symbol definition linker error, or something similar - that's why you need to include only declaration of the function inside header file. However, there are exceptions for this - for example, you may declare your function inline - other answers explain this approach.
So, now myfunction.h contains the function declaration:
#ifndef MY_FUNCTION_H
#define MY_FUNCITON_H
// declaration
int myfunction();
#end if
myfunction.cpp contains the function definition:
int myfunction()
{
return 4;
}
Now, in file1.cpp and in file2.cpp you want to use this function, so you're including myfunction.h:
// file1.cpp
#include "myfunction.h"
// somewhere in the file
void foo()
{
std::cout << myfunction();
}
... and in the second file:
// file2.cpp
#include "myfunction.h"
// somewhere in the file
void bar()
{
/// ...
std::cout << myfunction();
}
Header files in C and C++ are a language artifact. They are the consequence of the fact, that C and C++ can be implemented as a single-pass compiler. In contrast, Pascal - for example - has a two-pass compiler, that skips over unknown entities during the first pass, and fills in the missing bits in a second pass. Consequently, in C and C++ every type, object, and method must be declared before it can be used. This is the main responsibility of header files.
Header files are expanded into any file that includes them. In other words: The preprocessor replaces the statement #include "foo.h" with the contents of the file "foo.h". With this being the case you need to be careful to not violate the single definition rule: An entity must not be defined more than once.
To meet both requirements you have two options: Declare and define the function in the header, using the inline keyword, or declaring it in the header only, and defining it in another compilation unit.
The following code illustrates both solutions:
// foo.h
inline void foo() {
// Method is implemented in this header file.
// It is marked 'inline' to prevent linker errors
// concerning multiply defined symbols.
...
}
Delaration in header only, implementation in another compilation unit:
// foo.h
extern void foo();
// foo.cpp (or another compilation unit)
void foo() {
...
}
Regardless of which solution you go with, you can use foo() from any compilation unit. If you want to use it from "main.cpp" the code would look something like this:
// main.cpp
#include "foo.h"
int main() {
foo();
}
So you have a function which is used in all your header files, why don't you make a utility.h which keeps track of these types of functions and inline the functions in the .h ?
Declare the function prototype in a custom header file:
int add(int a, int b);
let say header file name is myfunction.h and include it wherever you need the function.
now you can define a function on another.cpp or main.cpp
int add(int a, int b){
return a+b;
}
include your custom header file like this:
#include "myfunction.h"
remember your main.cpp and other cpp files and the new header file should be in the same path.
If you have two files:
main.cpp
#include "func.h"
int main(){
hello();
std::cout<<" world!\n";
return 0;
}
& func.h
#ifndef FUNC_H
#define FUNC_H
#include <iostream>
void hello(void){
std::cout<<"hello";
}
#endif
iostreams objects and functions e.t.c will work fine from within main.cpp.
This posts answers sum up #ifndef pretty well if you would like to know more.

Referencing C functions in static library from C++

I have a static library of functions written in C. Let's say the header file is called myHeader.h and looks like:
#ifndef MYHEADER_H
#define MYHEADER_H
void function1();
void function2();
#endif
function1 and function2 aren't anything too special. Let's say they exist in a file called impl1.c which looks like:
#include "myHeader.h"
void function1() {
// code
}
void function2() {
// more code
}
All of the code mentioned so far is compiled into some static library called libMyLib.a. I'd rather not modify any of the code used to build this library. I also have a C++ header (cppHeader.h) that looks like:
#ifndef CPPHEADER_H
#define CPPHEADER_H
class CppClass {
private:
double attr1;
public:
void function3();
};
#endif
Then cppHeader.cpp looks like:
#include "cppHeader.h"
#include "myHeader.h"
// constructor
CppClass::CppClass(){}
void CppClass::function3() {
function1();
}
When I try to compile this, I get an error about an undefined reference to function1(). I believe that I've linked everything properly when compiling. I'm pretty rusty in my C++. I'm sure that I'm just doing something stupid. I hope that my simple example code illustrates the problem well enough.
Thanks in advance for any help!
The other solution (to the one suggested originally by Yann) is to surround your "C" header with:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
Which saves you from having to remember to do:
extern "C" {
#include "foo.h"
}
every place you use foo.h
Make sure to use:
extern "C" {
#include "myHeader.h"
}
Or else the C++ compiler will generate symbol names which are name-mangled.