Tag Archives: c++

Programming Pariahs – goto Statements

xkcd: gotoSource: http://xkcd.com/292/

Interestingly, although I do not believe I’ve ever been formally taught how goto works, I have been told on numerous occasions in classes that it’s something to avoid while programming. In fact, during one of my introductory programming courses, I distinctly remember the TA scoffing at my usage of goto in a C# program (where it was actually required). I’ll walk through the rationale behind the advice after a quick explanation of how goto is used in programming.

So, how does this newfangled goto thing work?

goto is used to jump to another location in a program. Upon reaching a goto statement, your program will jump to wherever the goto commands it to.

Though the details of goto differ between programming languages, here’s an example in C++ to print “I hate using loops!” five times:

#include <stdio.h>

int main()
{
int i = 0;

this_is_a_label:
   printf("I hate using loops!\n");
   i = i + 1;
   if (i < 5)
      goto this_is_a_label; // jump to the label if we're not done

   return 0;
}

This code has the following output:

I hate using loops!
I hate using loops!
I hate using loops!
I hate using loops!
I hate using loops!

Notice the label on line 7, “this_is_a_label:“. Labels are used as locations that you can jump to with a goto statement. The statement “goto this_is_a_label;” tells the program to jump to that label and continue execution from there.

Alright, now why “shouldn’t” I use goto?

Jumping around in code can make it very hard to process mentally while reading it, especially once the code becomes more complex than just one loop. For example, try figuring out what this program does:

#include <stdio.h>

int main()
{
    // Using nested goto loops
    int x = 1;
    outer_loop_begin:
        int y = 1;

        inner_loop_begin:
            printf("(%i,%i)\n", x, y);
            ++y;
            if(y < 4) goto inner_loop_begin;
        // inner loop done

        ++x;
        if (x < 4) goto outer_loop_begin;
    // outer loop done

    return 0;
}

It’s certainly less intuitive than this example using for loops:

#include <stdio.h>

int main()
{
    // Using nested for loops
    for(int x = 1; x < 4; ++x)
    {
        for (int y = 1; y < 4; ++y)
        {
            printf("(%i,%i)\n", x, y);
        }
    }

    return 0;
}

Both of the above examples have the same output:

(1,1)
(1,2)
(1,3)
(2,1)
(2,2)
(2,3)
(3,1)
(3,2)
(3,3)

As I’m sure you could imagine, improper/abusive use of goto can make a program significantly harder both to understand and to debug. You can use goto in a number of clever ways, but most places where you could be using goto you should generally be using some other part of the language (a loop structure, a function call, etc.).

When should I use goto?

The summary version is: whenever you are required to, or whenever it makes your code clearer. The latter is very subjective, so I won’t touch too much on that; however, it’s important to know when you need to use a goto statement.

Exiting from Nested Loops (C++, other languages)

Say hypothetically you’re inside nested loops, and you want to exit the entire structure, not just the loop you are in. Traditionally, a break statement is your trusty tool for exiting a loop, but that will only get you to the outer loop. For example:

#include <iostream>

int main()
{
    int searchValue = 2;

    // Search for a certain j value. Once it's found, exit the search loops
    // and exit the program.
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 5; ++j)
        {
            if (j == searchValue)
            {
                std::cout << "Found value " << searchValue
                          << " at (i,j): (" << i << "," << j << ")"
                          << std::endl;
                break; // exit our loops and print the completion message
                // BUG: breaks to the outer i loop
            }
        }
    }

    std::cout << "Search completed!" << std::endl;

    return 0;
}

You were hoping for the following output:

Found value 2 at (i,j): (0,2)
Search completed!

But you ended up with this!

Found value 2 at (i,j): (0,2)
Found value 2 at (i,j): (1,2)
Found value 2 at (i,j): (2,2)
Found value 2 at (i,j): (3,2)
Found value 2 at (i,j): (4,2)
Search completed!

The break statement at line 18 is only exiting your inner for loop. Once that break is hit, i gets increased by one and the loops continue going! To get the desired result, a goto statement will do the trick:

#include <iostream>

int main()
{
    int searchValue = 2;

    // Search for a certain j value. Once it's found, exit the search loops
    // and exit the program.
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 5; ++j)
        {
            if (j == searchValue)
            {
                std::cout << "Found value " << searchValue
                          << " at (i,j): (" << i << "," << j << ")"
                          << std::endl;
                goto search_done; // exit our loops and print the completion message
            }
        }
    }
search_done:

    std::cout << "Search completed!" << std::endl;

    return 0;
}

An alternative would be wrapping the loops in a function and returning where the goto is, but depending on where your loop is being called and what work is being done inside of it, goto may be the better choice.

“Falling through” non-empty cases in a switch statement (C#)

Traditionally, if you want multiple cases to do the same thing in a switch statement, your code will look something like this:

switch(direction)
{
    case WEST:
        goWest();
        break;
    case NORTH:
    case SOUTH:
    case EAST:
        System.out.println("There is no exit in that direction");
        break;
    default:
        // Invalid argument
        throw new InvalidArgException("Ya dun goofed!"); // they dun goofed.
        break;
}

This works fine in C#, unless you want to do something in a case before falling through it. In many language, simply omitting the “break;” statement at the end of the case will allow this functionality; however, this is not the case in C#: “A jump statement such as a break is required after each case block, including the last block whether it is a case statement or a default statement. With one exception, (unlike the C++ switch statement), C# does not support an implicit fall through from one case label to another. The one exception is if a case statement has no code.” (MSDN source). This is a good thing in that you won’t have an obscure bug caused by forgetting to put in a break statement; however, it requires using a different technique to fall through your cases.

If you want to “fall through” a non-empty case, you must explicitly state which case to go to:

switch(direction)
{
    case WEST:
        goWest();
        break;
    case NORTH:
        logSomethingHere();
        goto case EAST;
    case SOUTH:
    case EAST:
        System.out.println("There is no exit in that direction");
        break;
    default:
        // Invalid argument
        throw new InvalidArgException("Ya dun goofed!"); // they dun goofed.
        break;
}

Notice the “goto case” at line 8.

Other Uses

There are assuredly other reasons to use goto out there, especially because each programming language is different; however, two examples is enough for this particular article. Check the documentation for your programming language of choice!

References / Recommended further reading

The goto Statement – MSDN

goto (C# Reference) – MSDN

Wikipedia’s article on Goto, especially the Criticism and Decline section.

Avoiding Cracking Under Pressure

Sometimes, when working on a project, you get stuck.

The Problem

Recently, I was working on (what should have been) an elementary programming exercise: get the player to rotate around an object in 3D when a key is held down. I’d immediately started tackling the problem from the angle of “OK, how do I rotate around an arbitrary axis?”. Big mistake.

It’s pretty easy to make an error (or twenty) when you’re writing this out in code: (Image source)

For days, I just could not get the code to work. The player quickly developed a knack for teleporting all over the place, but despite his new-found skills with wizardry, he still wouldn’t rotate around the ball.

The Solution

Eventually, I gave up and stepped away from the problem for a while. A few days later, after a full night’s rest, I sat down in front of my laptop, scrapped all the code I had, and started from scratch. I got it working in less than an hour.

Lesson learned: Sometimes, you need to step back and take a break. In retrospect, I feel kind of silly for getting stuck for a few days on this one. :)

Here’s the (somewhat unoptimized) code to calculate the offset to move by each frame:

// Helper method to re-calculate the translation vector each frame while the
// player is rotating around the ball
// returns the offset the camera should move by
Ogre::Vector3 FrameUpdateListener::calculateRotation() {
 // get player position
 const Ogre::Vector3 playerPosition = GameState::getInstance()->getPlayerCamera()->getPosition();

 // get ball position
 const Vector3D* const pBallPosition =
 GameState::getInstance()->getBall()->getBoundingVolume()->getCenter();
 const Ogre::Vector3 ballPosition(pBallPosition->x, pBallPosition->y, pBallPosition->z);

 // get vector for player relative to ball
 const Ogre::Vector3 localPlayerPosition = playerPosition - ballPosition;

 // get theta (angle to rotate by)
 const int direction = isRotatingClockwise ? 1 : -1;
 const Ogre::Radian theta(static_cast<Ogre::Real>(direction * 0.05f)); // angle to adjust by

 // store cos/sin in temp variables to save calculations
 const Ogre::Real cosTheta = Math::Cos(theta);
 const Ogre::Real sinTheta = Math::Sin(theta);

 // calculate new player position
 // (rotate player position around Y axis)
 Ogre::Vector3 newPlayerPosition;
 newPlayerPosition.x = cosTheta * localPlayerPosition.x - sinTheta * localPlayerPosition.z;
 newPlayerPosition.z = sinTheta * localPlayerPosition.x + cosTheta * localPlayerPosition.z;
 // newPlayerPosition.y = localPlayerPosition.y; // commented to save the calculation, uncomment if you need this later for some bizarre reason

 // calculate dx and dz
 Ogre::Real dx = newPlayerPosition.x - localPlayerPosition.x;
 Ogre::Real dz = newPlayerPosition.z - localPlayerPosition.z;

 // return the offset vector
 return Ogre::Vector3(dx, 0, dz);
}

Woot! Global Game Jam Postmortem

This past weekend, I participated in Global Game Jam. My group of five created Woot, a puzzle game programmed in C++/DirectX 11.

Overall, the event went awesomely. I definitely did not expect to have as much fun as I did!

Some observations:

  • We spent a longer time than I thought we would hammering out a game concept. The theme for this year was “Extinction,” and that’s all we had to go on. I’m accustomed to having more restrictions on game concepts, or at least walking into a project with some idea of what’s going to happen. With Global Game Jam, we started with a completely blank slate. Though it was more of a challenge, I liked it!
  • We surprisingly ended up going with C++ and DirectX 11 for our game, rather than something simpler, primarily because our game required rotating the entire game level. One of my group members had a basic game engine built from an earlier project which allowed us to do this relatively easily compared to trying to hack something together in, say, XNA.
  • Our group was mentioned in the Democrat and Chronicle’s article on the game jam. Score!
  • We ended up with surprisingly awesome art assets. Ben Snyder (one of my group members) managed to create some pretty cool sounds and images for our game!
  • Even though the event is only 48 hours, getting enough sleep would have made things a thousand times easier for me. Skimping out on sleep ultimately does not actually net you more productivity.

Overall, I had a great time, and I definitely plan to take part in Global Game Jam next year!

Books!

Because I’m a bit of a programming fanatic, I picked up a two books recently: Game Programming Gems and Effective C++: 55 Specific Ways to Improve Your Programs and Designs.

Effective C++ was recommended to me by one of my professors. Although I’ve only gotten through the first chapter thus far, this book is definitely an excellent resource! Effective C++ looks like a solid way to go from just knowing C++’s syntax and how it works at a basic level, to understanding how to use C++. The first few items alone have already caused me to look differently at how I program; pulling that off in a couple dozen pages is rather impressive.

Game Programming Gems is a book I’ve been meaning to pick up for a while now. Though I’d heard of the series before, I never thought too much about it until I sat down and looked at someone’s copy of the first book in the series. After reading a section or two, I was sold immediately. I’ve only looked at a small few bits and pieces thus far, but I can already tell this book–and, likely, the entire series–is something I’ll come back to again and again.