Compile issue for multiple definition [SOLVED]

Hi
I’m trying to write my own code and I need to write some functione to different .cpp and .h files. So my sketch is made by the main file (a .ino one, the web IDE created it for me when I choose to start a new project) with an include for the new .h file with the declaration of functions and variables I need. The same include is inside the .cpp file that contains the functions definitions.
Now the problem: when I try to verify my code, the compiler say that all the variable are double defined and abort.
I try to use #ifndef / #define / #endif statements to have a single inclusion of .h file, but it doesn’t solve the problem.

#playground.ino:

    #include "lmt871.h"
    ... my code ...

#lmt871.cpp:

    #include "lmt871.h"
    ... my code ...

#lmt871.h:

    #ifndef LMT_H
    #define LMT_H
    ... variable and function declarations ...
    #endif

Anyone can help me?
Thanks

P.S. I read about that #include “application.h” thing, but adding it on every files doesn’t solve the problem.

Without seeing the code or the exact error message, we can only offer guesses, so please post those. :slight_smile:

If you’re defining functions in the header file, it’s possible to get a linker error since the same function is then defined in more than one module. Be sure to only put the declaration in the header file and then the function body in the .cpp file.

Sorry, this is the error:

In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from lmt871.cpp:1:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from playground.cpp:2:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
playground.o:(.bss+0x10): multiple definition of `mVinf'
lmt871.o:(.bss+0x4): first defined here
playground.o:(.bss+0x14): multiple definition of `mVsup'
lmt871.o:(.bss+0x0): first defined here
playground.o:(.data+0x1c): multiple definition of `mV'
lmt871.o:(.data+0x4): first defined here
playground.o:(.data+0x110): multiple definition of `arrayDim'
lmt871.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [86478ad9583bbedc1252ae91d73a2f6cb278580cf813a1e653d4d6ffe1d0.elf] Error 1

That one is the .h code:

#include "application.h"
#ifndef LMT871_H
#define LMT871_H

int arrayDim = 61;
int mV[]={
    2767,2754,2740,2727,2714,2700,2687,2674,
    2660,2647,2633,2620,2607,2593,2580,2567,
    2553,2540,2527,2513,2500,2486,2473,2459,
    2446,2433,2419,2406,2392,2379,2365,2352,
    2338,2325,2311,2298,2285,2271,2258,2244,
    2231,2217,2204,2190,2176,2163,2149,2136,
    2122,2108,2095,2081,2067,2054,2040,2026,
    2012,1999,1985,1971,1958};
int mVsup, mVinf;
double getTemp(int millis);

#endif

and the .cpp one:

#include "application.h"
#include "lmt871.h"

double getTemp(int millis){
    double temp = 0;
    for (int i = 0; i <= arrayDim; i++) {
        if (millis <= mV[i]) {
            temp = i - 10;
            mVsup = mV[i];
            mVinf = mV[i-1];
        }
    }
    double decimal = (millis-mVinf) / ((mVsup - mVinf)/10);
    temp += decimal;
    return temp;
}

playground.ino is basically a tinker firmware with

#include "application.h"
#include "lmt871.h"

and a call to getTemp().

Thanks. Yep, my suspicions were correct! :slight_smile: It's a linker error because the same symbols are being defined in the cpp modules.

You can fix this by moving the declaration to your lmt871.cpp file, and changing the header file to:

const int arrayDim = 61;
extern int* mV;
extern int mVsup, mVinf;
double getTemp(int millis); 

This tells the compiler that somewhere else there are these variables, and the linker finds them in the compiled lmt871.cpp file.

1 Like

Sorry, but I didn’t get it…
In lmt871.h file I declare some variables (and initialise a pair of them) and a function. In lmt871.cpp I don’t declare anything, I only define the function getTemp.
I’m not an experienced programmer, but I used to work like this: declaration on .h file and definition on .cpp file.
In fact if I change the code the way you suggest, I get another error:

lmt871.o: In function `getTemp(int)':
/spark/compile_service/shared/workspace/2_compile-server2/core-firmware/build/lmt871.cpp:16: undefined reference to `mV'
/spark/compile_service/shared/workspace/2_compile-server2/core-firmware/build/lmt871.cpp:16: undefined reference to `mVsup'
/spark/compile_service/shared/workspace/2_compile-server2/core-firmware/build/lmt871.cpp:16: undefined reference to `mVinf'

If I’m not wrong, that make sense because those variables are not extern for the function getTemp. I’m more inclined to think there is a problem with the dual inclusion of lmt871.h…

I'm guessing you didn't do this. You need to define the missing variables in your cpp file, like

int mV;
int mVsup, mVinf;

That way they are only defined once. The header allows other code to reference them, without redefining them.

2 Likes

Yes, you guessed right!
I’m not sure if it was QT or something else, but I’m sure I was using variable definition on .h files… Or maybe I’m completely wrong and learning java programming fried my brain.
Anyway, thanks!
The only note is I didn’t specify “external” on mVinf and mVsup, but I completely deleted them from .h and defined on .cpp (I don’t need to use them on main .ino file). Other two variables are now defined as const because so they are.
Thanks again.

1 Like