Thursday, June 17, 2010

Safely casting stl iterators

for use in begin/end contexts.

It is not straightforward to cast, for example, an std::vector<float>::iterator to a float pointer. The post here has a solution. But, consider the following situation:

struct vec3f{
float x,y,z;
};
std::vector<vec3f> vertices;
float *begin_ptr = vertices.begin(); // doesn't work
float *end_ptr = vertices.end(); // doesn't work

std::for_each(begin_ptr, end_ptr, do_something);

The pointers are going to be used in a combination with a reinterpret_cast<> and some algorithm. In this case data access will only be performed if begin_ptr != end_ptr. We can simply let:

float * begin_ptr = reinterpret_cast<float*>(&vertices[0]); // safe even for empty vectors
float * end_ptr = begin_ptr + (vertices.end() - vertices.begin())*3;

Which for an empty vector gives begin_ptr==end_ptr. It is a bit sketchy to rely on operator [] to not do any bounds checking, though. std::vector's doesn't, but other containers might.

Wednesday, June 9, 2010

Code syntax coloring

Good stuff. Source and instructions. Maybe some nice auto-indentation in the future?


class A{
A(){}
};

Debugging with gdb - catching asserts

Note to self.

When gdb encounters a failing assert in your source code the program is aborted (SIGABRT) and you’re sometimes left with nothing...?
Program terminated with signal SIGABRT, Aborted.
The program no longer exists.
(gdb)
Not really. Its just hiding in another thread.

(gdb) info thread

will tell you where to find it. A simple issue of thread # switches context and gets your precious stack back. You can also configure gdb to handle signals as described here.