In the C++ programming language Arduino is based on, a name must be declared before it is referenced. Since a definition is also a declaration, you can accomplish this by ordering the definitions so that each name is defined before it is referenced in the program (as you have done). However, that approach is not always convenient for the organization of the program, and sometimes it's not even possible.
The alternative is to use function prototypes, where you declare only the signature of the function. So you only need to put all the prototypes at the top of your program and then you can arrange the definitions in any way you like.
This is a complex subject for the people Arduino is intended to make embedded systems accessible to, so the approach Arduino used is to automatically generate prototypes for all the functions in the .ino/.pde files of the sketch which don't already have a prototype, inserting those generated prototypes before the code is compiled as C++.
That prototype generation system works perfectly 99.99% of the time, but it turns out that it's actually a very complex task. So in some cases the prototype generation system doesn't get it right, which results in there being bugs in invisible code.
If you turn on verbose output during compilation and then check the last commands in the black console pane at the bottom of the Arduino IDE window after compiling, you'll see the path to the temporary build folder that contains the preprocessed sketch files. This is what the your sketch looks like after preprocessing:
#include <Arduino.h>
#line 1 "E:\\electronics\\arduino\\temp\\sketch_dec16a\\sketch_dec16a.ino"
String Serialinput = "start";
#line 3 "E:\\electronics\\arduino\\temp\\sketch_dec16a\\sketch_dec16a.ino"
void setup();
#line 12 "E:\\electronics\\arduino\\temp\\sketch_dec16a\\sketch_dec16a.ino"
State getState();
#line 18 "E:\\electronics\\arduino\\temp\\sketch_dec16a\\sketch_dec16a.ino"
void loop();
#line 3 "E:\\electronics\\arduino\\temp\\sketch_dec16a\\sketch_dec16a.ino"
void setup() {
// put your setup code here, to run once:
}
enum State {
START
};
State getState(){
if(Serialinput == "start"){
return State.START;
}
}
void loop() {
switch (getState()) {
case START:
Serial.print("start");
break;
}
}
This line is the generated prototype for your "getState" function:
State getState();
You can see it was added above the declaration of the State type. This is the cause of the error.
The sketch preprocessor only generates prototypes when the sketch author hasn't already provided their own, so the workaround for this issue is to add the prototype for your "getState" function to your sketch at the appropriate location, after the declaration of the State type:
enum State {
START
};
State getState();
After that, you'll get another error, which this time is a legitimate bug in your code. You need to use the scope resolution operator if you want to scope the enum value into its type. So instead of this:
return State.START;
Do this:
return State::START;