10 years, 10 months ago.

Why does my #ifndef not work?

Hi all,

I'm trying to get this (fairly simple) code working for a drum machine. It uses a ton of pins so I've got a separate header file to define all the digital/analog ins and outs.

main.cpp has:

include the mbed library with this snippet

#include "mbed.h"
#include "definitions.h"
#include "readknobs.h"

readknobs.cpp also needs definitions.h:

include the mbed library with this snippet

#include "mbed.h"
#include "definitions.h" 

So main.cpp would compile definitions.h twice. Except I've got definitions.h as follows:

include the mbed library with this snippet

#ifndef _DEFINITIONS_H
#define _DEFINITIONS_H

#include "mbed.h"

//Analog Ins
AnalogIn tmp(PTC2);
AnalogIn sw(PTC5);
AnalogIn fill(PTC3);

//Drum Noises
DigitalOut Kick(PTC6);
DigitalOut Snare(PTC10);
DigitalOut HHOpen(PTC11);
......
(loads more definitions...)
....

#endif

It was my understanding that #ifndef would prevent the compiler from trying to define all the pins twice, but it comes up with the "multiply defined" error for all of the pins...

Any ideas or solutions?

Thank you very much in advance!

Think on the whole thing as a neccesary hierarchy. File containing int main() was the main file and its header was the main header. Other headers should include only definitions very exclusive to any secondary file.

posted by Juan Ramon Fuentes 29 Jun 2013

Thanks a lot for the help from both of you. I guess I was being a bit sloppy with my code by asking for definitions all over the place. With my clumbsy novice code, I've decided that the only pin that both .cpp files use can just be an input for my "readknobs" function. That way it's only defined in one place. Let's hope it works!

posted by George Cochrane 29 Jun 2013

3 Answers

10 years, 10 months ago.

Your definitions.h file contains indeed definitions, that is statements that actually claim memory. Header files should only contain declarations, i.e. tell the compiler what identifiers mean but not claim any memory for code or data. If you do, the code compiles fine but the linker complains that symbols have multiple DEFINITIONS. Data declarations use "extern", function declarations have no body and type definitions must not have a variables list. e.g.: class{}; is ok but class{}obj; is not. enum tag {}; is ok but enum tag{} var1, var2; is not. extern int i1; is a declaration int i1; is a definition, it allocates space for the integer and initialises it (for non-auto variables) always put your definitions (and local (static) declarations) in the cpp file and put only the public interface in the h file.

Accepted Answer

Thank a lot, that makes a lot of sense from the errors I've been getting. Very sorry to need this spelling out, but what am I now declaring in my definitions.h file if my definitions.cpp is a long list of AnalogIn kick(PTC2); DigitalIn switch(PTC3); DigitalIn snare(PTE5); .... etc.? I've tried making definitions.cpp a function that's called in the main.cpp and readknobs.cpp but that doesn't work well, and is a bit of a silly way of doing it. I'm just unsure of what to include in a header for a file that only contains analog and digital pin descriptions :s

posted by George Cochrane 01 Jul 2013

The following compiles and links successfully:

//main.cpp
#include "mbed.h"
#include "other.h"

DigitalOut myled(LED1);

int main() {
    use();
    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}

//other.h
extern DigitalOut myled;
void use();

//other.cpp
#include "mbed.h"
#include "other.h"

void use()
{ myled = 1;
}
posted by Ad van der Weiden 01 Jul 2013

Fantastic. I feel like I tried so many permutations, but your example does what I need very well. Thanks a lot!

posted by George Cochrane 01 Jul 2013
10 years, 10 months ago.

Remove the #include mbed.h inside definitions.h The same mbed.h is included twice in readknobs.cpp and main.cpp as they include first mbed.h and then definitions.h

10 years, 10 months ago.

Think on the whole thing as a neccesary hierarchy. File containing int main() was the main file and its header was the main header. Other headers should include only definitions very exclusive to any secondary file.

Yepp, my reorganisation with definitions.h only in the main.cpp works well. The other function now has an input of the pin value

posted by George Cochrane 29 Jun 2013