Forget that you ever knew that the goto command existed
Using goto can produce spaghetti code that is difficult to debug
There is never any need to use the goto command, certainly with your level of experience
Forget that you ever knew that the goto command existed
Using goto can produce spaghetti code that is difficult to debug
There is never any need to use the goto command, certainly with your level of experience
I read that is not a good idea to use the GOTO but for my skill level I don't see another option.
While your answer is correct and appreciated I suspect you missed the point. I believe @el_supremo's rhetorical question was directed specifically to @BulldogLowell to bring his attention to a datatype issue in the code he posted. In the best case the snippet is confusing. In the worst case the for-loop is unbounded.
In what way does your example NOT work? I mean, it's got some minor syntax errors (no type for test, no closing brace for loop), and some logic errors (the "bailout" code will be reached after the loop finishes as well as when the goto works. and the for loop limits/types are questionable), and it probably all gets optimized away by the compiler, but the "goto" itself is about right.
Here's a corrected version that actually does something...
byte r, g, b;
void setup() {
Serial.begin(38400);
}
void loop() {
for (r = 0; r < 10; r++) {
for (g = 10; g != 0; g--) {
for (b = 0; b < 10; b++) {
if (Serial.read() > 0) {
goto bailout;
}
Serial.println("do something");
}
}
}
Serial.println("\n\n *********** End of Loop *********\n");
delay(500);
return;
bailout:
Serial.println("\n========= Bailout works ===========");
delay(1000);
}
Leaving aside the fact that you don't modify test in this loop and it will never be >250, there's a couple of ways to treat this.
Any code with goto can be written without goto. Theoretically - I think Wirth proved this as a mathematical fact. But sometimes, using a goto makes a lot of sense. To rewite this without goto, you need to check the condition in each loop:
void loop() {
for (r = 0; r < 255 && test <= 250; r++) {
for (g = 255; g > -1 && test <= 250; g--) {
for (b = 0; b < 255 && test <= 250; b++) {
Serial.println("do something");
}
}
}
Serial.println("works");
}
Using a goto is clearer and neater.
Java supports breaking out of neeply nested loops, C++ doesn't.
Another way to do this is to make use of the behaviour of the return statement:
void loop() {
findSolution();
Serial.println("works");
}
void findSolution() {
for (r = 0; r < 255; r++) {
for (g = 255; g > -1; g--) {
for (b = 0; b < 255; b++) {
if (test > 250)
return;
Serial.println("do something");
}
}
}
}
But this is something of a hack: the loops possibly don't really belong in a separate function. The goto is neat, makes sense, and is not "spaghetti code". I used to code BASIC back in the 80's, I know what spaghetti code actually looks like. This isn't - it's simply exiting out of a deeply nested loop.
Perhaps something like this. (I don't think that 'we' on the arduino forums recommend functions nearly enough. This is a case where they help, aside from the usual "readability" reasons.)
byte r, g, b;
void setup() {
Serial.begin(38400);
}
void loop() {
if (rgbloop()) {
Serial.println("\n\n *********** End of Loop *********\n");
delay(500);
} else {
Serial.println("\n========= Bailout works ===========");
delay(1000);
}
}
byte rgbloop() {
for (r = 0; r < 10; r++) {
for (g = 10; g != 0; g--) {
for (b = 0; b < 10; b++) {
if (Serial.read() > 0) {
return 0; // Bail out
}
Serial.println("do something");
}
}
}
return 1; // return success
}
I've submitted a pull request to fix the bug in the goto example code:
jucasan:
btw, why most of the examples in the reference pages are so bad?
I don't know, but it's easy enough to fix. You can submit fixes or bug reports to the reference-en repository, which contains all the Arduino Language Reference content. The Arduino team is pretty good about merging pull requests to that repo in a timely manner. For more information, see:
If you don't have a GitHub account, or want to discuss potential changes first here on the forum, then please do create a thread here.
Thank you all of you guys.
I'm working to make a RGB strip controlled by a joystick.The xPosition controls the "program" (colors and sequence) and the yPosition controls the intensity. This part needs to be implemented yet.
It might not be the cleaner code, I'm sure there are better ways to do this but is working and eventually can improve the code.
Needed the GOTO in order to get out of the loops without delay when I move the joystick.
void switch_to_value_100 ()
{
bool bailout = false;
for (i = 0; i <= 255; i ++)
{
analogWrite(ledR, i);
analogWrite(ledG, LOW);
analogWrite(ledB, LOW);
Serial.println(" ");
Serial.print(programSelector);
Serial.print(" Red Transition ");
// Serial.print(" i= ");
// Serial.print(i);
xPosition = analogRead(xPin);
if (xPosition >= 540) { // bail out on sensor detect
i = 0;
programSelector = programSelector - 1;
goto bailout;
}
if (xPosition <= 480) { // bail out on sensor detect
i = 0;
programSelector = programSelector + 1;
goto bailout;
}
}
delay(1000);
for (i = 255; i >= 0; i--) {
analogWrite(ledR, i);
analogWrite(ledG, LOW);
analogWrite(ledB, LOW);
Serial.println(" ");
Serial.print(programSelector);
Serial.print(" Red Transition ");
// Serial.print(" i= ");
// Serial.print(i);
xPosition = analogRead(xPin);
if (xPosition >= 540) {
programSelector = programSelector - 1;
i = 0;
goto bailout;
}
if (xPosition <= 480) { // bail out on sensor detect
i = 0;
programSelector = programSelector + 1;
goto bailout;
}
}
bailout:
Serial.println("works");
Serial.println(programSelector);
delay(1500);
}