The issue occurs when I try to work with multiple files in VS Code / PlatformIO.
So I built an example to show the problem:
The linker (firmware.elf) says: 'multiple definition of 'variable';'
var.h:
#ifndef var_h
#define var_h
#pragma once
#include <Arduino.h>
int variable;
void set_var(int number);
#endif // var_h
var.cpp
#include "var.h"
void set_var(int number){
variable = number;
}
main.cpp
#include <Arduino.h>
#include <SPI.h>
#include "var.h"
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.print(variable);
delay(2000);
}
platformio.ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
I've already tried using either #pragma once
or #ifndef ...
exclusively, but it didn't work. Same error.
CodePudding user response:
You seem to misunderstand how header guards (your #ifndef var_h
and associated directives) work and also how declarations of 'external' variables work.
The header guards (either the aforementioned or the #pragma once
directive) will prevent multiple inclusion/processing of that file from any given, single translation unit (TU) but not from different TUs. So, for example, if one source file has multiple #include "var.h"
lines – or if it also includes another header which itself has a #include "var.h"
line – then those guards will prevent multiple inclusions. However, when you compile "var.cpp" and "main.cpp" (separately), the 'context' is reset for each one. Thus, each of those compilations will see the int variable;
line, so causing multiple definitions.
In your case, what you need to do is specify in the header that variable
is an int
but is defined elsewhere: extern int variable;
. Then, in only one source file (most likely "var.cpp") provide the actual definition, with a line like int variable;
(preferably, with an initial value, though: int variable = 0;
).