I am getting error messages from the mbed C++ compiler that seem to be indicative of malfunctioning include guards.
In main.cpp, I include my header file as follows:
#include "mbed.h"
#include "sample.h"
This is my sample.h:
#include "mbed.h"
#ifndef STUFF_H
#define STUFF_H
/* LEDs */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
/* Subroutines */
void sweepLEDs();
void pulseLEDs(int numPulses);
void clearLEDs();
#endif
In sample.cpp, I am including sample.h as follows:
#include "sample.h"
In both main.cpp and sample.cpp, I am referring to variables led1, led2, led3, led4
without declaring them. However, the compiler is outputting these complaints:
" Symbol led1 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)." ... " Symbol led4 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)."
Are my include guards written improperly? Or is there some other issue?
(For reference, here is the link to the mbed.h source)
You need to mark the declarations as "extern" like this:
Then define them (i.e. allocate storage for them) in sample.cpp by using the expression you used to have in the header.
The issue is a misunderstanding of what include guards do. Include guards prevent the compiler from seeing the same content again in the same translation unit (for the same .cpp file). They do not prevent separate translation units from seeing the same code.
In your header file, you define (not just declare) the variables. Therefore every translation unit which includes the header creates its own copy of those variables.
The correct way to do it is to define the variables in a .cpp file and only declare them in the header (the include guards should be there anyway, to prevent multiple inclusion in the same translation unit).
That is, in your file sample.h, prefix your variables with
extern
and remove the initializer (so they are only declared, not defined), and define them in the corresponding .cpp file (the one where also the functions are defined), by putting the exact definitions from your header there.In an unrelated note, you should put the
#include "mbed.h"
in sample.h inside the include guards, because some compilers optimize compile speed for such guards, and that optimization doesn't work if there's material outside the include guards. Note that this is not really a correctness issue (assuming mbed.h is properly protected by include guards as well), but a compiling performance issue.