Include error / multiple definition

Hi all,

since I encoutered a problem in another project, I just created a simple basic project with the same structure. I get the same errors here and I don't get it because I actually thought I implemented a protection for multiple including.

My structure is:

./test/
./test/test.ino
./test/head.cpp
.test/head.h

My code is:

test.ino

#include "head.h"

uint8_t myint = 8;

void setup() {}
void loop() {}

head.cpp:
#include "head.h"

head.h:

#ifndef MYTESTCONST
    #define MYTESTCONST

    #include <Arduino.h>
    #include <Ethernet.h>

    extern uint8_t myInt;

    EthernetClient myClient;

#endif

I get the following errors:

Kern wird kompiliert ...

Using precompiled core: C:\Users\xxxxx\AppData\Local\Temp\arduino\cores\arduino_avr_mega_cpu_atmega2560_6872bf0382a2d9afb59ed198fc836747\core.a

Linking everything together...

"C:\Users\xxxxx\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega2560 -o "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB/test.ino.elf" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\sketch\head.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\sketch\test.ino.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\Dhcp.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\Dns.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\Ethernet.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\EthernetClient.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\EthernetServer.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\EthernetUdp.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\socket.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\Ethernet\utility\w5100.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\libraries\SPI\SPI.cpp.o" "C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB/..\..\cores\arduino_avr_mega_cpu_atmega2560_6872bf0382a2d9afb59ed198fc836747\core.a" "-LC:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB" -lm

C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\sketch\test.ino.cpp.o (symbol from plugin): In function `myClient':

(.text+0x0): multiple definition of `myClient'

C:\Users\xxxxx\AppData\Local\Temp\arduino\sketches\0F40A7007DF25F1928450B3BE76905BB\sketch\head.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

Mehrere Bibliotheken wurden für "Ethernet.h" gefunden

Benutzt: C:\Users\xxxxx\OneDrive - xxxxx\Privat\Projekte\Arduino\libraries\Ethernet

Nicht benutzt: C:\Users\xxxxx\AppData\Local\Arduino15\libraries\Ethernet

Bibliothek Ethernet in Version 2.0.2 im Ordner: C:\Users\xxxxx\OneDrive - xxxxx\Privat\Projekte\Arduino\libraries\Ethernet wird verwendet

Bibliothek SPI in Version 1.0 im Ordner: C:\Users\xxxxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\libraries\SPI wird verwendet

exit status 1

Compilation error: exit status 1

Actually I thought the #ifndef prevents head.h from being included multiple times...?

multiple times in the same file (compilation unit), that is if you were doing this

.ino

#include "head.h"
#include "head.h"
#include "head.h"
#include "head.h"
#include "head.h"

uint8_t myint = 8;

void setup() {}
void loop() {}

you would be fine.

the challenge is that you include it both in head.cpp and the .ino, so the variable gets defined twice


if the .ino needs to know the EthernetClient then declare it extern in the .h and define it in the .cpp this way it's only defined once.

if the .ino does not need it, then just define it in the .cpp

it's usually a bad idea to define (define == allocate the memory - versus declare just tell the compiler it exists and what it is) something in a .h

Allright, that works. I actually wanted to put all the stuff I'll never touch again in the .h file to clean up the .ino file.

That's were my misunderstanding came from, thank you for clarification!

Problem solved, thanks for the quick reply!

Change to
./test/head.h