The snippet below, part of a class, functions as desired without a default case and without an ending break. I conclude then that the compiler secretly adds these things (or their equivalents) anyway even though I didn't. If that's true there would be no advantage in memory use or execution time by omitting these things. Does this sound right?
I get that it may seem a little awkward and is probably bad form.
switch (_flashState) {
case begin_T1_time:
digitalWrite(_PIN_TO_FLASH, _IS_OUTPUT_INVERTED ^ 0x01);
_timerAcc = millis(); // Reset the timer
_flashState = dwell_T1_time;
[[fallthrough]];
case dwell_T1_time:
if (millis() - _timerAcc < _T1_Preset)
break;
[[fallthrough]];
// Begin_T2_time:
digitalWrite(_PIN_TO_FLASH, _IS_OUTPUT_INVERTED ^ 0x00);
_timerAcc = millis(); // Reset the timer
_flashState = dwell_T2_time;
[[fallthrough]];
case dwell_T2_time:
if (millis() - _timerAcc < _T2_Preset)
break;
// _flashState = begin_T1_time;
// break;
// default:
_flashState = begin_T1_time;
} // End of switch
A "break" is the same result as a "break" in a for-statement or a while-statement. It breaks out of the switch-case. It is optional for the switch-case-statement (optional everywhere).
The "default" in the switch-case is also optional.
You are used to a certain way the switch-case is used and the compiler might give warnings when it is used otherwise. But there are not many rules for the switch-case, you can almost do whatever you want. Your code is not bad, it is okay.
It is, for example, allowed to put the "break" somewhere deep in layers of if-statements, or the "default" at the top.
Removing the ending "break" should not make any difference.
The "default" can be omitted when not needed.
I think there is a underlying problem. You should write source code that is easy to read and to maintain. The "default" can be handy to capture an unwanted value, to avoid that a bug causes a avalanche of problems. Let the compiler take care of the generated binary code.
You should not try to be smart and make ugly code.
I wasn't inclined to leave it that way I was just playing around with trying to make it shorter and possibly more efficient and was mildly surprised when it still worked.
I assumed it was necessary and the compiler was somehow invisibly adding it (or including something that gives the same effect) by itself. I've been disabused of that notion since learning that break and default are optional.
I don’t get the purpose of the fallthrough, say you enter with begin_T1_time you intialize _timerAcc And change the state.., so going to the next case has no effect at that point in time the delta time will be zero so you’ll break anyway…
As I wrote before: "You should not try to be smart and make ugly code", so in my world, this single line has three severe bugs:
if (_enabled ^ _IS_INPUT_INVERTED) {
The two 'bool' variables are used as bits, the 'xor' operates on those bits and the result of the 'xor' is converted into 'bool' for the condition of the if-statement.
The fallthrough was in lieu of the comment "fallthrough is deliberate". What I've read recommends one or the other after a case so that humans understand the lack of a break and [[fallthrough]] tells the compiler there's no need for a warning message.