Please can someone help with this. I have written a simple sketch to try to understand why I cannot get goto to work in a main program I am working on. (I am inexperienced at C++ , and although I know goto is not advised, I think it would be simpler for my application.
However I cant get the simple sketch (attached) to work either. It will not compile with error "label1 Label2 used but not defined". Goto is listed in the Arduino reference & I cannot see what is wrong.
int a = 0;
void setup() {
Serial.begin(9600);
int a = 0;
}
void print() {
label2; {
Serial.println("label2 has sent me back to label1");
}
label1: {
Serial.println("am at label1");
}
for (int a = 0; a < 100; a++)
{
Serial.println(a);
delay(100);
}
if ( a >= 50)
{ Serial.println("going to label2");
goto label2;
}
}
void loop() {
// put your main code here, to run repeatedly:
//label2: Serial.println("am at label2");
delay(5000);
goto label1;
}
I got it to compile by making label1() and label2() into functions that can be called, and got rid of the print() function.
int a = 0;
void setup() {
Serial.begin(9600);
int a = 0;
}
void label2() {
Serial.println("label2 has sent me back to label1");
label1();
}
void label1() {
Serial.println("am at label1");
for (int a = 0; a < 100; a++)
{
Serial.println(a);
delay(100);
}
if ( a >= 50)
{ Serial.println("going to label2");
label2();
}
}
void loop() {
// put your main code here, to run repeatedly:
//label2: Serial.println("am at label2");
delay(5000);
label1();
}
In addition to the typo @CrossRoads pointed out, you can not jump (e.g. GOTO) into the middle of another function. Labels inside your Print() function are only visible to code inside that function.
There are many, many better alternatives to GOTO. What are you actually trying to do?
Lots of problems here with the first being you can't use goto to jump into a function. But really, you should study the use of the while and do while control structures and not use goto. I assure you that your code will easier to follow without gotos.
Another problem in your code is variable scope. The for loop declares a variable "a" which is local to that loop and is not the same that is referenced in the if statement, which is a global variable. The global variable will always be zero, so the a>=50 expression will always be false.
49
50
going to label2
label2 has sent me back to label1
I am at label1
0
1
2
int a = 0; // <<<< makes a into a global variable
void setup() {
Serial.begin(9600);
int a = 0; // <<<< int not needed here
}
void label2() {
Serial.println("label2 has sent me back to label1");
label1();
}
void label1() {
Serial.println("I am at label1");
for (int a = 0; a < 100; a++) // <<< int not needed here
{
Serial.println(a);
delay(100);
if ( a >= 50)
{ Serial.println("going to label2");
label2();
}
}
}
void loop() {
// put your main code here, to run repeatedly:
//label2: Serial.println("am at label2");
delay(5000);
label1();
}
int a = 0;
void setup() {
Serial.begin(9600);
a = 0;
}
void label2() {
Serial.println("this is label2");
;
}
void label1() {
Serial.println("this is label1");
for (a = 0; a < 100; a++)
{
Serial.println(a);
delay(10);
if ( a >= 50)
{ Serial.println("a is >= 50");
break;
}
}
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Starting loop()");
delay(3000);
label1();
label2();
}
Starting loop()
this is label1
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
a is >= 50
this is label2
Starting loop()
this is label1
0
1
after the professor told us he'd fail us for using goto, i finally figured out their valid use in unix and other examples
in your code , there's no need for a goto, this isn't assembly code. (on my first embedded project, my supervisor said there's a bunch of assembly programmers writing assember programs in C).
the conventional approach is when some cleanup or post processing is needed (not illustrated)
do {
// something
} while (a >= 50);
but where i've used goto in such a situation is
void func () {
do {
for (int a = 0; a < 100; a++)
{
if (someErrorCondition)
goto err;
}
} while (a >= 50);
// normal exit
return;
err:
// error exit
printf ("%s: something bad happened\n", __func__);
return;
}
Thanks for the answers but the code was just for me to try to get to understand what the compiler needs to accept the goto labels definition. It complains that they are not defined.
There were some basic errors, some redundant code, and one 'goto' trying to jump to a label that was not in scope. I fixed what I could and worked around the invalid code. It's been running for 567 iterations without crashing.
The output (using shorter loop to reduce waiting):
4
5
going to label2
label2 has sent me back to label1
Am at label1. 565
0
1
2
3
4
5
going to label2
label2 has sent me back to label1
Am at label1. 566
0
1
2
3
4
5
going to label2
label2 has sent me back to label1
Am at label1. 567
0
1
2
3
The corrected code:
int Iterations = 0;
void setup()
{
Serial.begin(115200);
delay(200);
Serial.println("In setup().");
}
void print()
{
goto label1;
label2:
Serial.println("label2 has sent me back to label1");
label1:
Serial.print("Am at label1. ");
Serial.println(Iterations++);
for (int a = 0; a < 10; a++)
{
Serial.println(a);
delay(100);
if ( a >= 5)
{
Serial.println("going to label2");
goto label2;
}
}
}
void loop()
{
// goto label1; // Can't go to a label outside the current function
// Instead: call the function:
print();
}
if this is just for knowing it. Fine. As previously said:
using goto in code leads to what's called "spaghetti"-code.
Program-execution jumps up and down in a way that will it make very hard to understand your code after 4 weeks. You can ask any software-developer beeing a hobbyist or a professional they all avoid goto completely.
My point of view: yiu should learn functional programming.
Every function does one thing.
not sure what you wanted with your conditions seems akward to me.
anyway what would be so hard about coding that if an errorCondition occurs the do-while-loop will be exited;
void func () {
do {
for (int a = 0; a < 100; a++)
{
}
} while (a >= 50 && !someErrorCondition );
if (someErrorCondition) {
printf ("%s: something bad happened\n", __func__);
}
return;