Why is goto the devil and exiting programs question.

This is a discussion on Why is goto the devil and exiting programs question. within the C++ Programming forums, part of the General Programming Boards category; I fail to see how for loops are easier to read, though, because essentially, they are the same thing. Code: ...

  1. #16
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    I fail to see how for loops are easier to read, though, because essentially, they are the same thing.
    Code:
    for (int i = 0; i < 10; i++);
    Same as:
    Code:
    int i = 0;
    while (i < 10)
        i++;
    Not much difference, is there?

    As for goto: try writing a flow chart. Then add conditions and gotos and you'll see arrows all over the place in the end. That's why it's called a mess. This is why we use loops.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,598
    Quote Originally Posted by Elysia
    Not much difference, is there?
    With the for loop, I can mentally register the kind of iteration to expect (of course, the same can be said of the while loop, but as a different kind of iteration). Furthermore, in your example, the scope of i is restricted to the for loop, but extends beyond the while loop.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    Yes, well I mostly targeting the loop condition which is usually the part of the loop that has the most problems grasping. And both for and while use the same type of condition. Loop while this condition is true.
    It makes me wonder why they didn't add a loop that loops UNTIL the condition is true, such as Visual Basic has. For many, it is easier to grasp than inverted logic.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,598
    Quote Originally Posted by Elysia
    Yes, well I mostly targeting the loop condition which is usually the part of the loop that has the most problems grasping. And both for and while use the same type of condition. Loop while this condition is true.
    However, you would then be comparing where they are the same, not where they are different. If you want to choose between them, where they differ would be important.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #20
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,436
    Quote Originally Posted by Elysia View Post
    Yes, well I mostly targeting the loop condition which is usually the part of the loop that has the most problems grasping. And both for and while use the same type of condition. Loop while this condition is true.
    It makes me wonder why they didn't add a loop that loops UNTIL the condition is true, such as Visual Basic has. For many, it is easier to grasp than inverted logic.
    Not following you here Elysia.
    C++ loops are essentially loop until false. But loop until true is what seems inverted logic since you are validating the next iteration on a negative predicate(?).

    Anyways, In any case you can implement loop until true, by removing the condition and using exit statements (break, return, throw, and... goto(!))
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  6. #21
    Super Moderator
    Join Date
    Sep 2001
    Posts
    4,913
    I would say it's mainly because C was designed to provide very a bare minimum set of abstractions, and is often just syntactic sugar for common operations in Assembly. It wasn't designed to be easy to understand for noobs. Visual Basic to larger extent was.

  7. #22
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    In over a decade, there was only one time when I was tempted to use goto to get out of a deeply nested bunch of loops & if statements... Unfortunately Java wouldn't let me use goto in the place I wanted, so I had to make the code even uglier.
    But in all other cases, there is a better way to do things other than using goto, and in all cases, it is never required to use goto. So until you become a lot more experienced, it's better to just stay away from it and pretend goto doesn't exist.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  8. #23
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    Quote Originally Posted by Mario F. View Post
    Not following you here Elysia.
    C++ loops are essentially loop until false. But loop until true is what seems inverted logic since you are validating the next iteration on a negative predicate(?).

    Anyways, In any case you can implement loop until true, by removing the condition and using exit statements (break, return, throw, and... goto(!))
    I meant that in VB, there is Do...Loop While and Do...Loop Until. Two different ones, and when you think about it, we want things to loop UNTIL a condition is true. That is often how my mindset is. Dunno about others, but I'd rather think a lot of people think like that.
    So then the while loop becomes inverted logic. Loop until this is FALSE essentially.
    Thankfully, it is easy to fix by just inverting the logic, but it's interesting nevertheless.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #24
    Registered User
    Join Date
    Feb 2009
    Posts
    37
    Here is an illustration of how much using loops can improve the readability of code. I'll use loops and gotos to solve a simple problem, creating a multiplication table:

    Using for loops:
    Code:
    	for (int a = 1; a <= 6; ++a) {
    		for (int b = a; b <= a * 6; b += a) {
    			std::cout << std::setw (3) << b << " ";
    		}
    		std::cout << "\n\n";
    	}
    Directly converting those for loops to gotos:
    Code:
    	int a = 1;
    start_loop_a:;
    	if ( !(a <= 6)) goto end_loop_a;
    	int b = a;
    start_loop_b:;
    	if ( !(b <= a * 6)) goto end_loop_b;
    	std::cout << std::setw (3) << b << " ";
    	b += a;
    	goto start_loop_b;
    end_loop_b:;
    	std::cout << "\n\n";
    	++a;
    	goto start_loop_a;
    end_loop_a:;
    It is possible to do it using only one loop by adjusting the logic slightly, though not much more elegantly:
    Code:
    	int a = 1;
    	int b = a;
    start_loop_c:;
    	if ( !(a <= 6))
    		goto end_loop_c;
    	std::cout << std::setw (3) << b << " ";
    	b += a;
    	if ( !(b <= a * 6)) {
    		++a;
    		b = a;
    		std::cout << "\n\n";
    	}
    	goto start_loop_c;
    end_loop_c:;

  10. #25
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Heark back to languages like some of the original BASIC implementations. These languages only supported IF-statements of the form:

    Code:
    IF expr THEN stmt
    Where STMT is a single statement. In most situations this FORCES you to use goto in order to jump to a code block that implements anything more complex than a single statement. This usage was so common that often you could omit the keyword "goto" altogether and it would be implied:

    Code:
    This:
    IF expr THEN 200
    
    Means the same as:
    IF expr THEN GOTO 200
    As a result, programs were a horrible mess of gotos, scattered code blocks, and obscure control flow.

    goto was kept around in the C language because, as you remember, the C language was created in order to implement the UNIX kernel, a piece of code with strict performance and size requirements. goto can be used in some clever (read: hard to understand) ways that slightly improve performance or decrease code size. These considerations are less and less relevant.

    In addition, compilers perform control flow analysis during optimization, in order to infer the relationships betweens variables and data flows. Some of the more powerful optimization algorithms depend on control flow graphs that are structured in a certain way -- using structured concepts automatically guarantees that the flow graph is reducible. But once you start using goto, you may create a flow graph that the analyzer cannot understand, and the result is that the compiler applies zero optimization to the entire function, or at least to a subgraph.

    In short, using goto can counterintuitively HURT performance by confusing the hell out of the compiler. Compilers used to be dumb, and you needed goto to help them out. Now they're smarter than you.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #26
    Registered User
    Join Date
    Jul 2009
    Posts
    34
    So, to pack it into a metphore, using a goto statement at the wrong time is basically as appropriate as running naked across the stadium during a football game.

  12. #27
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,299
    Quote Originally Posted by Jefff View Post
    So, to pack it into a metphore, using a goto statement at the wrong time is basically as appropriate as running naked across the stadium during a football game.
    In that case, using it at the "right time" (assuming there is such a thing) is like running naked across the stadium when it's empty. If you're lucky nobody will notice or care.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #28
    Registered User
    Join Date
    Jul 2009
    Posts
    34
    I found another issue where I would find goto useful, but what are the alternatives?
    This function should restart itself when an invalid menu section is selected.



    Code:
    /*	 Main Menu	 */
    
    #include "stdafx.h"
    #include <iostream>
    #include "menu.h"
    using namespace std;
    
    
    
    void menu()	{
    	cout<<"#########################"<<endl;
    	cout<<"FILE I/O TEST APPLICATION"<<endl;
    	cout<<"#########################"<<endl<<endl;
    	
    	
    	cout<<"<1>List entries"<<endl;
    	cout<<"<2>Display specific entry"<<endl;
    	cout<<"<3>Create new entry"<<endl;
    	cout<<"<0>Exit program"<<endl;
    	cout<<"Select function: ";
    
    
    
    	//Get selected menu
    	int m;
    	cin>>m;
    
    
    	switch (m)	{
    
    		case 0:
    			exitprogram();
    
    			
    
    
    
    	}
    }
    
    
    void exitprogram()	{
    	cout<<"<0>Exiting...."<<endl;
    }

    Now I can think of several ways:

    1. Use goto to hop back to the start of it.
    2. Use some form of return value that tells the main function to start menu() again. However I seem to mess up something when trying to use return values. What is the correct syntax to assign a return value of a function to a variable?

  14. #29
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    If an invalid entry is selected, you can simply call the function recursively. For that you can add a default case which calls the menu function.
    >>What is the correct syntax to assign a return value of a function to a variable?

    for eg f() returns a value.
    Code:
    int i;
    i=f();
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  15. #30
    Registered User
    Join Date
    Jul 2009
    Posts
    34
    Would calling a function itself create some weird and dangerous itself calling loop? The compiler warned when I tried.

    Also this appears to run the function itself when assigning it to a variable:

    Code:
    int i;
    i=f();

    I modified the menu function to look like that:
    It should return the variable m to the main program when it is within range, if not, it should return -1.

    Code:
    int menu()	{
    	cout<<"#########################"<<endl;
    	cout<<"FILE I/O TEST APPLICATION"<<endl;
    	cout<<"#########################"<<endl<<endl;
    	
    	
    	cout<<"<1>List entries"<<endl;
    	cout<<"<2>Display specific entry"<<endl;
    	cout<<"<3>Create new entry"<<endl;
    	cout<<"<0>Exit program"<<endl;
    	cout<<"Select function: ";
    
    
    
    	//Get selected menu
    	int m;
    	cin>>m;
    
    	//Check if valid selection
    	if (m > 3 || m < 0)	{
    	cout<<"<ERROR>Invalid selection, returning to main menu..."<<endl;
    	return -1
    	}
    	else	{
    		return m;
    	}
    
    
    
    }

    Then I have to use a silly if/else in the main function to decide on how to proceed. And having a clunky if/else in my main function for that just feels wrong. I am trying to keep the main function totally clean (only use it to call function), so I would like to know how to tell a function to restart itself without using goto and without calling itself again and again.

Page 2 of 4 FirstFirst 1234 LastLast
Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21