Exception handling in C++.

March 9, 2010 at 8:46 pm (C++) (, , , )

I’ve been teaching a course on Data Structures in C++ for the University of Reykjavik. It has been a fun experience for me. I had to write a paper for some students that missed out the part on exception handling, so I thought about sharing it to the world too through my blog.

I will begin this post with a few examples on how to throw and catch errors. After that I will introduce a few classes from the C++ Standard Library that can be easily used. I will make an example class that extends the exception class from the C++ Standard Library and I will use it to throw an error and catch an error with an error message.

Now, let us begin! In C++ you can throw errors of any type. For example:

    throw 4;                    //int
    throw 3.3;                  //double
    throw false;                //bool
    throw 'c';                  //char
    throw string("test");       //std::string
    throw logic_error("test");  //class

And you can also catch an error of any type by using (…) in catch:

    throw 3.3;
catch (...)
    cout << "General error of any type" << endl;

If you want to throw and catch an error of the type string you would do it in the following way:

    throw string("I am a string");
catch (string s)
    cout << s << endl;

And as you can see from the example above, you can print the string we grabbed in catch. It would print “I am a string” to the console window. So basically you can throw an object of any type and catch it and use it for whatever reason you want. For example if I want to throw an error of the type integer I would do: throw 3; and if catch would grab an integer, then I would get an integer with the value 3.

Next I’m going to be more specific on how to throw an instance of a class as an error.

In C++ you have access to exception classes in the C++ Standard Library that you can use.
Here below you can see what exception classes are available. They’re indented depending on the inheritance tree.

    logic_error			(extends exception)
        domain_error		(extends logic_error)
        invalid_argument	(extends logic_error)
        length_error		(extends logic_error)
        out_of_range		(extends logic_error)
    runtime_error		(extends exception)
        range_error		(extends runtime_error)
        overflow_error		(extends runtime_error)
        underflow_error		(extends runtime_error)


The class out_of_range extends logic_error and logic_error is a class that extends exception.
Is there a good reason for having all those exception classes available? The main reason is to allow the user to be able to grab a specific error. Let’s assume that we only wanted to grab errors that are instance of the class out_of_range then it would be done in the following way:

    throw out_of_range("Error message");
catch (out_of_range e)
    cout << e.what() << endl;
catch (...)
    cout << "Some error that is not an instance of out_of_range" << endl;

If we got an error in the try clause that is not an instance of the class out_of_range, then catch (…) would grab it and print “Some error that is not an instance of out_of_range”.

And if the error was an instance of out_of_range then we would grab it in the catch (out_of_range e) and we would have an access to the function what() within the object e, like shown in the example above.

You may probably be thinking what function is what()? It’s a virtual function that is declared in the base exception class, of which out_of_range extends. It returns a char pointer to the error message supplied in the constructor.

Ok, so now we know how to throw an error that is an instance of a class and how to grab it with catch. Next I’m going to show you how to make your own exception class that extends the exception class in the C++ Standard Library.

In my case, the students were supposed to make an Integer(real number) class that would hold one integer and some function that returns true or false whether the integer is a prime number or not. Thus I will call my new class IntegerException.

I will make IntegerException extend exception, to do that you will need to include iostream and use the namespace std, then the header file for the class will look like the following code:

#include <iostream>
using namespace std;

class IntegerException :
	public exception

Ok great, now since our IntegerException class extends the exception class, then we can make the constructor of our class call the base constructor (the constructor in exception) with the appropriate error message. To do that we need to go to the implementation of our class (usually the .cpp file of the class, IntegerException.cpp) and then add the following to the constructor:

IntegerException::IntegerException() :
    exception("Error message")

Now our constructor will call the base constructor. The result is that when we call the what() function we will get the error message we supplied to the exception constructor. In this case what() will return a char pointer to “Error message”.

Example usage of the class:

    throw IntegerException();
catch (IntegerException e)
    // Here "Error message" will be printed out.
    cout << e.what() << endl;

However, now we are stuck with “Error message” every time we throw an error that is an instance of our class IntegerException. What if we want to have a different message depending on where we throw the error? That’s easy, we will just make the constructor of our class take the message as a parameter.

In the example below I will take a char pointer as a parameter and simply let the base constructor have the message:

IntegerException::IntegerException(char* strError) :

You may ask why I use char pointer instead of string as the parameter. That is because the constructor of the exception class wants to have const char *message as the parameter but not string. There’s nothing stopping us from using string, just change it to a char pointer by using the c_str() function in std::string. If we go the string way, the constructor will look like this:

IntegerException::IntegerException(string strError) :

So now we can throw an error that is an instance of the IntegerException class with any error message you want and we can easily grab it in catch and print out the error message.

Example of usage:

    throw IntegerException("Error handling is fun");
catch (IntegerException e)
    // Here "Error handling is fun" will be printed out.
    cout << e.what() << endl;

As you can see, exception handling is pretty straight forward. There’s one problem some people have run into, which is when they get divide by zero error. Divide by zero is not detected within the try clause. It was a c++ design decision. So be careful to always check if you divide by zero.

If something is unclear, feel free to comment and ask away 🙂

Thank you for reading!

Permalink 2 Comments

My latest work (TerrainGL).

December 4, 2009 at 12:37 pm (OpenGL)

I’ve always dreamed of writing a terrain engine, probably since I was around thirteen years old.

Now that I’m so lucky to be attending to a computer graphics class, I made that dream come true by making it as my final project. This blog will introduce the methods I use to draw the terrain, and my progress from day one.

My goal is to write a massive terrain engine, of which can scale up a lot without slowing down your PC. The terrain height values are taken from a 24 bit bitmap, by the whiteness of the pixels. The darker the texel is, the lower the vertex is.


Heightmap image

My first approach was very ugly, the terrain was drawn with GL_QUADS and it was also very slow. Next step was to draw it with GL_TRIANGLE_STRIP as it’ll require less vertices to draw each triangle.



Above, you may see that I only need 6 vertices to draw 4 triangles! When I was using GL_QUADS I needed 12 vertices, no sharing of vertices. Remember that sharing is always good! So you can see how I can dramatically decrease the vertices needed to draw triangles, meaning faster drawing and less OpenGL calls.

Here’s a preview of my first terrain:


The texture on the terrain is repeated all over it, so it looks like a golf course. The lighting calculation is really easy, all the normals face up (0.0f, 1.0f, 0.0f). If I calculated it correctly for each face, the lighting would not go smooth over the neighbour surface. What do I do? After a little search on Google I found a neat way, thanks to http://www.lighthouse3d.com/opengl/terrain/index.php3?normals.

Let’s take a look at this picture:

Each surface has a normal, n1, n2, n3 and n4. We are now calculating the normal for the vertex v. That vertex is shared between n1, n2, n3 and n4. What we do is really simple, we take the sum of all the normals v = (n1 + n2 + n3 + n4) and the normal vector v will then give us a smooth lighting between the neighbor surfaces.

Next step was to create a shader, a shader that would color the terrain more brown/grayish on slope areas, and after a specific height I want the texels to become more white (snow effect on highest areas).

If I want to use a shader, the default OpenGL pipeline would be replaced with it, thus I would lose the fog effect, the texture on the landscape, lighting and pretty much everything.
The solution wasn’t that hard, I found a shader with the help of Google that introduces Phong shading, it’s a lighting technique similar to the OpenGL one except it’s much faster. I used the one from http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/lighting.php

To handle the textures in the shader, I simply added it to the phong shading calculation.

gl_FragColor.r = texel.r * gl_FragColor.r;
gl_FragColor.g = texel.g * gl_FragColor.g;
gl_FragColor.b = texel.b * gl_FragColor.b;

The problem I faced next was that I had little knowledge on how to pass vertex information to the shader, how much slope it has and so and forth. After a little search I managed to find a good way, I simply store the color values of the vertices using glColor! That way the vertex shader can read the gl_Color and pass it to the fragment shader where all the coloring magic will happen.

On the vertex shader I simply do:

vcolor = gl_Color;

That way I can pass it to the fragment shader and simply modify the RGB calculation a bit:

gl_FragColor.r = texel.r*gl_FragColor.r*vcolor.r;
gl_FragColor.g = texel.g*gl_FragColor.g*vcolor.g;
gl_FragColor.b = texel.b*gl_FragColor.b*vcolor.b;

Voila! Now I have phong shading that can render the texture and add color variations to the texels using glColor!


The landscape without slope and fog calculation involved.

Landscape with fog and slope calculation involved.

Here we can see the sunset!

Picture after writing a simple game and using MDL (Half-Life models) renderer.

The collision detection was really simple to do, for each surface made up of 2 triangles, I found the equation of the two triangles and solved y from x and z. I wrote a tutorial on that HERE.

Please do comment if you want the shader or any additional information!

Permalink Leave a Comment

Solving y on a triangle in 3D space given x and z.

November 25, 2009 at 11:53 am (C++) (, , , , )

Yay, my second post.

I’ve been working on a final project at my university, University of Reykjavik for a computer graphics class.
Since I’ve always wanted to create a terrain engine since I was a kiddie, I thought why not? This was my opportunity to do it for once!

The problem I was facing was walking on the surface of the terrain. The y position of the camera was the max of the three points of the triangle I was standing on, which made the movement jerky, like stepping um stairs.

So how can we find the height or the y value for a specific x and z in a triangle? Easy, really! We’ll have to find the equation of a plane from 3 points. But first we need to define two vectors that lie on the plane:

Vector3 is a class of which has three floats; x, y and z.

Vector3 AB(points[1].x – points[0].x, points[1].y – points[0].y, points[1].z – points[0].z);
Vector3 AC(points[2].x – points[0].x, points[2].y – points[0].y, points[2].z – points[0].z);

So now we have two vectors AB and AC, which define a plane from the three points points[0], points[1] and points[2].

Next we’ll have to find the cross product of those two vectors: AB x AC, which will give us the normal vector of the plane.

Vector3 normal(AB.y * AC.z – AB.z * AC.y, AB.z * AC.x – AB.x * AC.z, AB.x * AC.y – AB.y * AC.x);

Normal vector

So now we have the normal vector of the plane. Normal vector is a vector which is perpendicular to the plane.

Next we’ll need to multiply one point of the three points that define the plane with the normal vector to get the equation of the plane.

Basically it’ll give us a number that I call the coefficient:

coefficient =normal.x * points[0].x +normal.y * points[0].y +normal.z * points[0].z;

So now we can get the height for a given x and z in the triangle!

height = (-normal.x*position.x -normal.z * position.z + coefficient) /normal.y;


Permalink 1 Comment