Antonio Castles
Antonio Castles

Reputation: 13

Switch case statement in function doesn't switch C++

I am trying to use two switch case statements in two different functions to control a micro-controller through serial packages, but one of the functions doesn't switch and the program loops indefinitely. One of the functions switches according to an enum:

enum class State {

 example_a,
 example_b,
 example_c

};

void serialTask(State stateArg, ObjectA exampleA, ObjectB exampleB, ObjectC exampleC, ObjectD exampleD) {
  switch (stateArg) {
    case State::example_a:
      Serial.println("Serial Task, example a");
      exampleA.doSomething();
      stateArg = State::example_a;
      break;

    case State::example_b:
      Serial.println("Serial Task, example b");
      exampleB.doSomething();
      stateArg = State::example_b;
      break;

    case State::example_c:
      Serial.println("Serial Task, example c");
      exampleC.doSomething();
      stateArg = State::example_c;
      break;
   }
};

I am giving it all the other objects as arguments because depending on the case I call their functions or modify their members.

The other function switches the value of the enum according to the serial port:

void stateSwitch(State stateArg) {
    if (Serial.available()) {
        uint8_t code = Serial.read();
        switch (code) {
        case 'a':
            stateArg = State::example_a;
            break;
        case 'b':
            stateArg = State::example_b;
            break;
        case 'c':
            stateArg = State::example_c;
            break;
   }
};

They later get called in my main.cpp like this:

ObjectA aObj;
ObjectB bObj;
ObjectC cObj;
ObjectD dObj;
volatile State stateObj;

void setup(){

stateObj = State::example_a;
Serial.begin(115200);


};

void loop(){

stateSwitch(stateObj);
serialTask(stateObj, aObj, bObj, cObj, dObj);

};

This is a simplified version of the problem but it illustrates the point. The program compiles but for some reason it cannot jump out of State::example_a. I am using a Teensy micro-controller with the Arduino framework in PlatformIO, an extension for Visual Studio. Thank you for your help.

Upvotes: 1

Views: 568

Answers (2)

paxdiablo
paxdiablo

Reputation: 881783

void serialTask(State stateArg, ...
    stateArg = State::example_a; // affects local copy only

This is pass by value, so a copy is made for the function. It does not echo any changes back to the original variable.

To do that, you need to pass it by reference:

void serialTask(State &stateArg, ...
    stateArg = State::example_a; // affects variable used in call

Note that you'll need to pass by reference in all functions that want to change the variable (so stateSwitch as well as serialTask).

By way of example, note the following:

#include <iostream>
void procA(int num) {
    num = 7;
}
void procB(int &num) {
    num = 42;
}
int main() {
    int num = 1; std::cout << num << '\n';
    procA(num);  std::cout << num << '\n';
    procB(num);  std::cout << num << '\n';
}

This will result in the three lines 1, 1 and 42, because the call to procA is pass-by-value which doesn't affect the passed variable, just the local copy of it.

On the other hand, procB, being pass-by-reference, does change the passed variable.

Note also that the call is similar regardless of whether you're passing by value or reference. You do not need to change the call in any way.


You may also want to examine the logic behind these things:

case State::example_a:  // current state
      Serial.println("Serial Task, example a");
      exampleA.doSomething();
      stateArg = State::example_a; // why set to same/original state?
      break;

It's very unusual for a state machine to force the state back to the value it was before executing the event. It may be okay since we can't see all your code but I'd just be careful there.

Upvotes: 1

Marshall Clow
Marshall Clow

Reputation: 16670

You are passing stateArg to stateSwitch by value.

That means that a copy is being made, and you are modifying the copy; not the original.

Upvotes: 1

Related Questions