I am working on my first arduino project, where I came across the following behavior I would like to understand. The following code compiles with no issues:
enum TestEnum {TestValue1};
void test(){}
void setup(){}
void loop(){}
void foo(TestEnum &testArg) {}
But switching the first two lines
void test(){}
enum TestEnum {TestValue1};
void setup(){}
void loop(){}
void foo(TestEnum &testArg) {}
results in the following errors when compiling:
D:\Path\to\Arduino-Sketches\foo\foo.ino:5:10: error: variable or field 'foo' declared void
void foo(TestEnum &testArg) {}
^~~~~~~~
D:\Path\to\Arduino-Sketches\foo\foo.ino:5:10: error: 'TestEnum' was not declared in this scope
D:\Path\to\Arduino-Sketches\foo\foo.ino:5:10: error: note: suggested alternative: 'isalnum'
D:\Path\to\Arduino-Sketches\foo\foo.ino:5:20: error: 'testArg' was not declared in this scope
D:\Path\to\Arduino-Sketches\foo\foo.ino:5:20: error: note: suggested alternative: 'test'
void foo(TestEnum &testArg) {}
^~~~~~~
test
Can anyone explain why an enum needs to be defined before all functions? Is this an Arduino IDE thing? If it is a general C++ thing, what is the rational for this?
It's caused by Arduino preprocessing from .ino to .cpp file. It's for "convenience" reasons so begginers doesn't have to add prototypes (you can only use functions after they are declared or defined) and of course #include <Arduino.h>. So:
void test(){}
enum TestEnum {TestValue1};
void setup(){}
void loop(){}
void foo(TestEnum &testArg) {}
Will be preprocessed as:
#include <Arduino.h>
#line 1 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_446733\\sketch_feb19a.ino"
#line 1 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_446733\\sketch_feb19a.ino"
void test();
#line 3 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_446733\\sketch_feb19a.ino"
void setup();
#line 4 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_446733\\sketch_feb19a.ino"
void loop();
#line 5 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_446733\\sketch_feb19a.ino"
void foo(TestEnum &testArg);
#line 1 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_446733\\sketch_feb19a.ino"
void test(){}
enum TestEnum {TestValue1};
void setup(){}
void loop(){}
void foo(TestEnum &testArg) {}
And as you can see all the function prototypes (declarations) apeared before any function definition (eg before test() {})
When you moved the function definition after the enum definition, it results into this:
#include <Arduino.h>
#line 1 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_473375\\sketch_feb19a.ino"
enum TestEnum {TestValue1};
#line 2 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_473375\\sketch_feb19a.ino"
void test();
#line 3 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_473375\\sketch_feb19a.ino"
void setup();
#line 4 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_473375\\sketch_feb19a.ino"
void loop();
#line 5 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_473375\\sketch_feb19a.ino"
void foo(TestEnum &testArg);
#line 2 "C:\\Users\\mikusm\\AppData\\Local\\Temp\\arduino_modified_sketch_473375\\sketch_feb19a.ino"
void test(){}
void setup(){}
void loop(){}
void foo(TestEnum &testArg) {}
Notice where the enum TestEnum {TestValue1};
ended in real .cpp file
Possible workarounds: