goto jump

Pages: 12
Neat :)
@seeplus I really like yours. I laughed :)
Last edited on
This is a general comment about code, including examples in this thread which avoid goto.

Very long functions and deeply nested blocks are more of a maintenance headache than a stray goto in a small function.

Sutter and Alexandrescu in 'C++ Coding Standards'
Avoid long functions. Avoid deep nesting.

Summary
Short is better than long, flat is better than deep: Excessively long functions and nested code blocks are often caused by failing to give one function one cohesive responsibility, and both are usually solved by better refactoring.

Discussion
Every function should be a coherent unit of work bearing a suggestive name. When a function instead tries to merge such small conceptual elements inside a long function body, it ends up doing too much. Excessive straight-line function length and excessive block nesting depth (e.g., if, for, while, and try blocks) are twin culprits that make functions more difficult to understand and maintain, and often needlessly so.

Each level of nesting adds intellectual overhead when reading code because you need to maintain a mental stack (e.g., enter conditional, enter loop, enter try, enter conditional, ...). ... Prefer better functional decomposition to help avoid forcing readers to keep as much context in mind at a time. Exercise common sense and reasonableness: Limit the length and depth of your functions


For instance, a stray goto somewhere in this code would not result in a maintenance disaster:

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <string>
#include <vector>
#include <random>
#include <cctype>

std::string pick_secret_word()
{
    static const std::vector<std::string> dictionary
    {
        "underground", "crocodile", "computer", "keyboard",
        "shuttle", "asteroid", "dictionary", "kaleidoscope"
        // and more more more
    };
    static std::mt19937 rng( std::random_device {}() ) ;
    static std::uniform_int_distribution<std::size_t> distrib( 0, dictionary.size()-1 );

    return dictionary[ distrib(rng) ] ;
}

std::string to_lower( const std::string& str )
{
    std::string result ;
    for( unsigned char c : str ) result += std::tolower(c) ;
    return result ;
}

void print( const std::string& secret, std::string guess )
{
    guess.resize( secret.size() ) ;
    for( std::size_t i = 0 ; i < secret.size() ; ++i )
        std::cout << ( secret[i] == guess[i] ? guess[i] : '*' ) ;
    std::cout << " [" << secret.size() << " characters]\n" ;
}

void print_instructions( const std::string& secret, std::size_t MAX_ATTEMPTS )
{
    std::cout << "~~~ Guess The Secret Word Game ~~~\nThe secret word has been chosen:\n" ;
    print( secret, {} ) ;
    std::cout << "You have " << MAX_ATTEMPTS << " attempts\n";
}

bool guess_word( const std::string& secret, std::size_t attempt_number )
{
    static const std::string counts = "123456789012345678901234567890";
    std::cout << "What is your attempt #" << attempt_number + 1 << "\n:"
              << counts.substr( 0, secret.size() ) << "\n:";
    std::string guess ;
    std::cin >> guess ;
    guess = to_lower( guess ) ;

    if( secret == guess ) return true ;

    print( secret, guess ) ;
    return false ;
}

int main()
{
    const std::size_t MAX_ATTEMPTS = 10 ;
    std::size_t attempt_number = 0 ;
    const std::string secret = pick_secret_word() ;
    print_instructions( secret, MAX_ATTEMPTS ) ;

    while( attempt_number < MAX_ATTEMPTS && !guess_word( secret, attempt_number ) ) ++attempt_number ;

    if( attempt_number < MAX_ATTEMPTS ) std::cout << "Congrats! You have guessed the secret word\n" ;
    else std::cout << "Sorry. The word was '" << secret << "'\n";
}




Structured design by 'top down' and 'step-wise refinement'.

See Wirth's seminal papers:
https://oberoncore.ru/_media/library/wirth_program_development_by_stepwise_refinement2.pdf
https://oberoncore.ru/_media/library/wirth_on_the_composition_of_well-structured_programs.pdf

For 'high level' programming, this is how I was taught to program. Before coding, we used to have to produce a structured design using this approach - which had to show the various 'iterations' of the design. This counted for half of the overall marks!
I like that first sentence of the first paragraph in the Introduction in the Program Development by Stepwise Refinement paper:

Programming is usually taught by examples.

And more than a few of the examples we see here beginning C++ students are required to follow are bad examples, bordering on atrociously bad.

Examples of what not to do.
Topic archived. No new replies allowed.
Pages: 12