C++ goto replacement

Hello, I am beginner in C++ and I would like to ask you if this is a good replacement for goto or not.
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
//GOTO WAY:

int main()
{
start:
	cout << "start" << endl;
	goto AB1;
AB1:
	cout << "AB1" << endl;
	goto AB2;
AB2:
	cout << "AB2" << endl;
	cin.ignore();
	goto start;
}

//Other way:

int AB1();
int AB2();

int main()
{
	cout << "start" << endl;
	AB1();
}

int AB1()
{
	cout << "AB1" << endl;
	AB2();
}

int AB2()
{
	cout << "AB2" << endl;
	cin.ignore();
	main();
}
you should not call main from anywhere nor recursively. Some compilers figure it out OK, but it is not ensured to work. I once had a compiler that tolerated double main and could compute a value for me using the return statement :) But this stuff is hackery. main is type int, and main is not called by anything; its a special "start here" part of your program.

Goto can be replaced many ways depending on what you want to do. If you goto a label above your current spot, that is a loop. If you go below, it is usually an if statement.

so you get something like

while(1) //start
{
code
}

goto AB1; //ok
AB1: //you went here, ok, this is normal program flow, it does nothing!

the internal labels do not do anything. You need a better example.

now, if they gotos were conditional, a function is good:

if(something)
goto ABC2;

is the same as
if(something)
ABC2(); //function call

or

if(something)
{
code //maybe no need for a function, maybe its just a little code
}

The bottom line is to forget goto when writing c++. Almost everything that can be done in the language is doable another, better way. There used to be 1 thing gotos were used for, and that was error handling of deep nested loops:

for()
for()
for()
{
if (some horrible failure condition)
goto out;
}


out:
if(epic_fail)
{
//error handler
}

but with the try/catch/throw stuff I believe even this usage is no longer accepted (?).
Last edited on
lets say I need to do this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
char next;

int main()
{
start:
	cout << endl << "Welcome " << endl;
	cout << "Type 1 or 2." << endl;
	cin >> next;
	if (next == '1') goto AB1;
	else if (next == '2') goto AB2;
AB1:
	cout << endl << "Welcome to AB1. " << endl;
	cout << "Type r to return or 2 to enter AB2." << endl;
	cin >> next;
	if (next == 'r') goto start;
	else if (next == '2') goto AB2;
AB2:
	cout << endl << "Welcome to AB2. " << endl;
	cout << "Type r to return or 1 to enter AB1." << endl;
	cin >> next;
	if (next == 'r') goto start;
	else if (next == '1') goto AB1;
}


I found a way to do it without goto
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
int AB1();
int AB2();
int selection();

char next;

int main()
{
	cout << endl << "Welcome" << endl;
	selection();
}

int selection()
{
	cout << "Type 1 or 2." << endl;
	cin >> next;
	if (next == '1') AB1();
	else if (next == '2') AB2();
}

int AB1()
{
	cout << endl << "Welcome to AB1." << endl;
	cout << "Type r to return or 2 to enter AB2." << endl;
	cin >> next;
	if (next == 'r') selection();
	else if (next == '2') AB2();
}

int AB2()
{
	cout << endl << "Welcome to AB2." << endl;
	cout << "Type r to return or 1 to enter AB1." << endl;
	cin >> next;
	if (next == 'r') selection();
	else if (next == '1') AB1();
}


Is it good or is there a better way to do it?
Last edited on
Hello Lager159,

I would say that the "goto" statement can be replaced with a while, do/while loop ro a switch/case.

Your second example is a better choice for a program because main calls AB1 which calls AB2 then returns to AB1 which returns to main to end the program. Since this happens calling main on line 38 is not necessary. And likely t lead to an endless loop with no way out.

Technically not need, but good form to put return 0; at the end of main.

Hope that helps,

Andy
You cannot call main this way. !!!
if (next == 'r') main();

This is just a language thing. Every other function it is ok, but main is special.
Last edited on
you should not call main from anywhere nor recursively. Some compilers figure it out OK, but it is not ensured to work.

Not to mention the fact that the C++ standard prohibits calling main() recursively.

You can collapse a lot of this logic and make it elegant and all with some variables and parameters. But I am not able to do that right this second. If you did that you can do all this stuff in one function with a little conditional logic. That isnt important here.

With what you have, you can do this:

int main()
{
start();
}

int start()
{
cout << endl << "Welcome" << endl;
cout << "Type 1 or 2." << endl;
cin >> next;
if (next == '1') AB1();
else if (next == '2') AB2();
}

int AB1()
{
cout << endl << "Welcome to AB1." << endl;
cout << "Type r to return or 2 to enter AB2." << endl;
cin >> next;
if (next == 'r') start();
else if (next == '2') AB2();
}

int AB2()
{
cout << endl << "Welcome to AB2." << endl;
cout << "Type r to return or 1 to enter AB1." << endl;
cin >> next;
if (next == 'r') start();
else if (next == '1') AB1();
}
Last edited on
I just did that when I read I should not call main :D Edited the previous post. Thanks all :)
Last edited on
No. Structure your code so that it does not need goto-like constructs.

Also, never call main(). C++ forbids it, and it is a bad idea in C as well. (main() is a special function.)

You can easily create a dispatch using enums or function pointers.
Topic archived. No new replies allowed.