Incrementing enum value

I am using enum instead of int to track the mode of a program.

I have these three modes:

enum Mode {
fixed,
changing,
music
};

I created a variable:
Mode currentMode = fixed;

Now if I want to use a button to change mode (increasing the value) this will give an error:
currentMode++;
however, the following line compiles:
currentMode = currentMode +1;
why would this be?

Enum is not int, it is a different datatype.
The increment operator is not defined to enums.

3 Likes

Surely the point of using an enum is to be able to use meaningful names for a state. If so, then incrementing one of the values is of little value as then you do not know the name of the current state and might just as well use a normal variable.

The compiler may ne OK with it but what about the poor human trying to read and understand the code ?

3 Likes

and what would you expect to get if currentMode == music when you add +1?!?

You could write a function which returns the "next" mode - including a solution what should happen with the "next" mode when in "music".

Incrementing an int makes sense if you are for example stepping through named menu items on a screen. It is not clear that incrementing a state variable makes sense.

Thank you all. I did not write it in the post but , yes of course there should be a way to go back to the first mode after the last (in this case music mode).
And yes, I do realize that it makes little sense to use int when in fact I was trying to make the code more legible.

You could write a function which returns the "next" mode - including a solution what should happen with the "next" mode when in "music".

maybe that's the best way... I will go for it

here it is:

void incrementMode(){
  currentMode = currentMode + 1;
  if (currentMode >= 3){
    currentMode = 0;
  }
}

It is the same thing but it acts behind the scene making the code more readable I suppose. Not sure If I can do better in this sense.
Admittedly I have I have also checked chatGPT :blush: which offers a more elegant one line code for going back to 0:
static_cast<Mode>((currentMode + 1) % 3
is the static cast needed though? :thinking:

I would use the enum as a enum.
Don't rely on the numbers behind the enumeration

just code it:

enum Mode {
  fixed,
  changing,
  music
};

Mode currentMode = fixed;

void next(Mode &in) {
  switch (in) {
    case fixed: in =  changing; break;
    case changing: in = music; break;
    case music : in =  fixed;
  }
}

void readable(Mode in) {
  switch (in) {
    case fixed: Serial.println(F("fixed")); break;
    case changing: Serial.println(F("changing")); break;
    case music : Serial.println(F("music"));
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println(F("n for next"));
}

void loop() {
  if (Serial.read() == 'n') {
    next(currentMode);
    readable(currentMode);
  }
}

when you change the order in the enum, the code will still work.
when you add enums, the compiler will warn you.

for short time:

2 Likes

You could define enums for firstMode and lastMode, so that it is clear what you are comparing/setting the mode to, and the code is not specific to the number of enums. It is possible for two enums to share the same value, so firstMode and fixed can both be 0.

1 Like

By convention, enum values are usually capitalized:

enum Mode {FIXED, CHANGING, MUSIC};
1 Like

That looks good. Let me study it...

Lots of useful advices guys thank you very much.

This is brilliant, I learned quite a few thing from you post! Thanks!!

1 Like

I just see that the readable function is incorrect, ... of course you should print the name of the case, and not the next name ...

I am not sure I understand how you would do that in practice... Noiasca's example sets specific behaviours on passing from one mode to another, which takes care of the last mode, but I am not sure if you mean the same thing or something different.

I try to answer:

in your post #7 you have a hardcoded 3 and a hardcoded 0.
so if you add a "FIRST_ELEMENT" in the beginning and a "LAST_ELEMENT" at the end of your enumeration, you could replace that hardcoded 3 and 0 with "LAST_ELEMENT - 1 " and "FIRST_ELEMENT +1". The code will work even if you add values between first and last element.

Sometimes you see something like "NUMBER_OF_ELEMENTS" as last entry to "count" the number of values.
Nowadays I advice against adding artificial values in the enumeration.

1 Like

Thanks I get it now!

so you are saying that would not favour this practice

I don't favour this practice, but you will see it in old programs/libraries for sure.

Thanks :+1: