Why would this not work:
void uselessFunctionDeclarationThatWillCauseError(int a) {}
typedef struct { char deviceName[15]; } SomeType;
int saveConfig(SomeType &something) {}
void setup() {}
void loop() {}
It will give errors:
/home/merc/Arduino/sketch_may5b/sketch_may5b.ino:3:16: error: 'SomeType' was not declared in this scope
int saveConfig(SomeType &something) {}
^~~~~~~~
/home/merc/Arduino/sketch_may5b/sketch_may5b.ino:3:26: error: 'something' was not declared in this scope
int saveConfig(SomeType &something) {}
^~~~~~~~~
/home/merc/Arduino/sketch_may5b/sketch_may5b.ino: In function 'int saveConfig(SomeType&)':
/home/merc/Arduino/sketch_may5b/sketch_may5b.ino:3:35: error: 'int saveConfig(SomeType&)' redeclared as different kind of symbol
int saveConfig(SomeType &something) {}
^
/home/merc/Arduino/sketch_may5b/sketch_may5b.ino:3:5: note: previous declaration 'int saveConfig'
int saveConfig(SomeType &something) {}
^~~~~~~~~~
exit status 1
Compilation error: 'SomeType' was not declared in this scope
Whereas this identical code, with the uselessFunctionDeclarationThatWillCauseError function out, will compile fine:
typedef struct { char deviceName[15]; } SomeType;
int saveConfig(SomeType &something) {}
void setup() {}
void loop() {}
I am at my wits end with this.
J-M-L
May 5, 2024, 8:22am
2
you are victim of Arduino's team trying to make the artists less dependant of C++ rules which say that "things" need to be declared before they are being used.
The IDE is trying to be smart and generates declarations for the functions (prototypes) you use before compiling and dump them at the beginning of the file or where it thinks it's appropriate, but sometimes get confused when you defined types or stuff not at the expected place. if you move the typedef at the top, then you won't get a compile error
typedef struct {
char deviceName[15];
} SomeType;
void uselessFunctionDeclarationThatWillCauseError() {}
int saveConfig(SomeType something) {}
void setup() {}
void loop() {}
PS: in C++ you don't need typedef for a struct, you can just write
struct SomeType {
char deviceName[15];
};
2 Likes
rsmls
May 5, 2024, 8:24am
3
My guess would be that apparently this:
will be interpreted as a specification and not just a declaration, which apparently causes the saveConfig to also be interpreted as such.
While the code without the first 'useless' function is taken as a declaration only (despite the {} on saveConfig) and as such, you don't get to the point of getting the same error.
Although @J-M-L 's explanation is really just...better.
J-M-L
May 5, 2024, 8:27am
4
there are a few GitHub bugs and forum's posts about this
for exemple
opened 07:56PM - 02 Oct 18 UTC
closed 07:32AM - 03 Oct 18 UTC
When the Arduino IDE attempts to generate the prototypes for a function where th… e types that are a part of that prototype are defined in a header file, the IDE does not always include the header file defining the type before the generated prototype is emitted to the file that is passed into G++.
[Code is available here](https://github.com/zachdeibert/arduino-ide-prototype-bug)
Build Output:
```
/home/zach/software/arduino-1.8.5/arduino-builder -dump-prefs -logger=machine -hardware /home/zach/software/arduino-1.8.5/hardware -tools /home/zach/software/arduino-1.8.5/tools-builder -tools /home/zach/software/arduino-1.8.5/hardware/tools/avr -built-in-libraries /home/zach/software/arduino-1.8.5/libraries -libraries /home/zach/Arduino/libraries -fqbn=arduino:avr:nano:cpu=atmega328 -ide-version=10805 -build-path /tmp/arduino_build_613863 -warnings=all -build-cache /tmp/arduino_cache_167137 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=/home/zach/software/arduino-1.8.5/hardware/tools/avr -prefs=runtime.tools.arduinoOTA.path=/home/zach/software/arduino-1.8.5/hardware/tools/avr -prefs=runtime.tools.avr-gcc.path=/home/zach/software/arduino-1.8.5/hardware/tools/avr -verbose /code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino
/home/zach/software/arduino-1.8.5/arduino-builder -compile -logger=machine -hardware /home/zach/software/arduino-1.8.5/hardware -tools /home/zach/software/arduino-1.8.5/tools-builder -tools /home/zach/software/arduino-1.8.5/hardware/tools/avr -built-in-libraries /home/zach/software/arduino-1.8.5/libraries -libraries /home/zach/Arduino/libraries -fqbn=arduino:avr:nano:cpu=atmega328 -ide-version=10805 -build-path /tmp/arduino_build_613863 -warnings=all -build-cache /tmp/arduino_cache_167137 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=/home/zach/software/arduino-1.8.5/hardware/tools/avr -prefs=runtime.tools.arduinoOTA.path=/home/zach/software/arduino-1.8.5/hardware/tools/avr -prefs=runtime.tools.avr-gcc.path=/home/zach/software/arduino-1.8.5/hardware/tools/avr -verbose /code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino
Using board 'nano' from platform in folder: /home/zach/software/arduino-1.8.5/hardware/arduino/avr
Using core 'arduino' from platform in folder: /home/zach/software/arduino-1.8.5/hardware/arduino/avr
Detecting libraries used...
"/home/zach/software/arduino-1.8.5/hardware/tools/avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-I/home/zach/software/arduino-1.8.5/hardware/arduino/avr/cores/arduino" "-I/home/zach/software/arduino-1.8.5/hardware/arduino/avr/variants/eightanaloginputs" "/tmp/arduino_build_613863/sketch/arduino-ide-prototype-bug.ino.cpp" -o "/dev/null"
Generating function prototypes...
"/home/zach/software/arduino-1.8.5/hardware/tools/avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-I/home/zach/software/arduino-1.8.5/hardware/arduino/avr/cores/arduino" "-I/home/zach/software/arduino-1.8.5/hardware/arduino/avr/variants/eightanaloginputs" "/tmp/arduino_build_613863/sketch/arduino-ide-prototype-bug.ino.cpp" -o "/tmp/arduino_build_613863/preproc/ctags_target_for_gcc_minus_e.cpp"
"/home/zach/software/arduino-1.8.5/tools-builder/ctags/5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "/tmp/arduino_build_613863/preproc/ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"/home/zach/software/arduino-1.8.5/hardware/tools/avr/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-I/home/zach/software/arduino-1.8.5/hardware/arduino/avr/cores/arduino" "-I/home/zach/software/arduino-1.8.5/hardware/arduino/avr/variants/eightanaloginputs" "/tmp/arduino_build_613863/sketch/arduino-ide-prototype-bug.ino.cpp" -o "/tmp/arduino_build_613863/sketch/arduino-ide-prototype-bug.ino.cpp.o"
add:3: error: 'number_t' does not name a type
number_t add(number_t a, number_t b) {
^
/code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino: In function 'void loop()':
arduino-ide-prototype-bug:7: error: 'add' was not declared in this scope
Serial.println(add(2, 2));
^
exit status 1
'number_t' does not name a type
```
C++ file generation:
```
#include <Arduino.h>
#line 1 "/code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino"
#line 1 "/code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino"
#line 1 "/code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino"
void setup();
#line 5 "/code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino"
void loop();
#line 3 "/code/github.com/zachdeibert/arduino-ide-prototype-bug/add.ino"
number_t add(number_t a, number_t b);
#line 1 "/code/github.com/zachdeibert/arduino-ide-prototype-bug/arduino-ide-prototype-bug.ino"
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.print("2 + 2 = ");
Serial.println(add(2, 2));
delay(1000);
}
#line 1 "/code/github.com/zachdeibert/arduino-ide-prototype-bug/add.ino"
#include "number.h"
number_t add(number_t a, number_t b) {
return a + b;
}
```
Workaround: Including all header files into the main INO fixes the problem, but that should not be required.
So, this dead-simple code illustrates the problem quite well:
template <typename VarType>
void printVar (VarType val) {
Serial.println(val);
}
void setup() {
printVar(7);
printVar(3.14159);
printVar("hello world");
}
void loop() {
}
As-is, it produces the compiler error:
Template:2: error: variable or field 'printVar' declared void
void printVar (VarType val){
^
Template:2: error: 'VarType' was not declared in this scope
exit status 1
variable or field 'printVar…
1 Like
This killed my Sunday morning programming session... I am so. Angry.
J-M-L
May 5, 2024, 8:56am
6
Once you know it it's not that bad.. Most of the time the IDE gets it right
You can also put your own function prototype somewhere after the typedef and before the function, that prevents the IDE from auto-generating a prototype for that particular function.
Yeah, I am calming down, trying to get this beast finished by tonight...
I am NOT a C/C++ developer. I have 30+ years experience in software development, but NOT in C/C++. I am limping my way towards polished code, but boy, it's hard work...
I wish you could program this with Rust...
Yep I just wrestled another similar issue... This time I think I am overwriting memory all over the shop. This is getting more and more fun...
This is my last head-banging exercise...
I don't know C/C++ very well and I am getting seriously flogged here!
I have a config object that is a little complicated:
Config getDefaultConfig() {
Config config;
config.checksum = 0;
config.mustRunInitialSetup = true;
strncpy(config.deviceName, "YOUR FEEDER", sizeof(config.deviceName));
config.deviceName[sizeof(config.deviceName) - 1] = '\0';
config.soilDryValue = 0;
config.soilLittleMoistValue = 0;
config.soilMoistValue = 0;
config.soilVeryMoistValue = 0;
config.trayNe…
system
Closed
November 1, 2024, 5:04pm
12
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.