views:

406

answers:

4

I've written a C++ matrix template class. It's parameterized by its dimensions and by its datatype:

template<int NRows, int NCols, typename T>
struct Mat {
    typedef Mat<NRows, NCols, T> MyType;

    typedef T value_type;
    typedef const T *const_iterator;
    typedef T *iterator;

    enum { NumRows = NRows };
    enum { NumCols = NCols };

    T m_data[NRows * NCols];

    // ... Lot's of operations and functions ...

// Some overloads
typedef Mat<2, 1, int> Vec2i;
typedef Mat<2, 1, float> Vec2f;
typedef Mat<3, 1, float> Vec3f;
typedef Mat<4, 1, unsigned char> Vec4ub;
typedef Mat<4, 4, float> Mat44f;
typedef Vec3f Vector;
typedef Vec4ub Color;
typedef Vec2f LonLat;

It's a fantastic little class that handles lots of vector arithmetic and linear algebra. Also, it is able to interface easily with both low level code (OpenGL) and high level code (PID and Kalman filters).

Its design seems sound to me, but that's not what this question is about. This class has one dreadful flaw: it is a dread to use in the debugger.

Because it is a struct that contains an array, there is always that one annoying level of indirection when examining variables in Xcode (and I assume in VisualStudio). This is further aggravated by the fact that Xcode sometimes fails to follow chains of pointers correctly and I can't examine the values at all. This happens if I have, say, a vector of these objects.

I realize that I could perhaps customize the debugger to somehow work with my type. But I was wondering if there is perhaps

a different way to store the data of my Matrix so that it has better "debugability"?

This is more of a "use your imagination" type question than one looking for a best-practices design. I'm just curious what alternative class layouts could be used while still maintaining the generic nature of the code.

+2  A: 

You could start by changing this:

T m_data[NRows * NCols];

to this:

T m_data[NRows][NCols];

That may help you some, as it gives the debugger a bit more of a clue about the structure of the data. Note that you are likely doing some array index math that would need to change/go away if you implement this modification.

Rick Copeland
You might also just union{} what you have with Rick's answer, so you break no code but enable an alternate viewing method.
GMan
Be careful with unions. They make it harder for the compiler to do alias analysis, so there may be a performance cost. And in this case, you wouldn't really gain anything.
jalf
This is not a sound idea performance-wise: you are allocating nCols chuncks of memory instead of 1
David Lehavi
@David: No, actually when you use the array syntax like this, the compiler will allocate a single, contiguous chunk of memory. That's the difference between allocating multidimensional arrays and allocating an array of pointers to arrays. Strange but true!
Rick Copeland
+3  A: 

These kind of Matrix classes are always tricky to debug. Unlike Rick, I prefer the data to be structured the way you have it (i.e., T m_data[NRows*NCols]), but you may want to add some methods to make testing a little easier; for instance, a method that prints the matrix automatically and a method to lookup a datum at a specific row and column can make your life easier:

void printMat() const;
void printMatToFile( const char *fileName ) const;
T &get(int row, int col);

I usually use the gdb debugger, which allows you to call a method while debugging. I don't know if your debugger supports this, so you may want to try using g++/gdb for testing, or some debugger that supports function calls while debugging.

Colin
There's no reason to have these methods be class members however. They could be free functions to avoid cluttering the class with debug-only functionality.
jalf
@Colin, @jalf, agreed both ways. I already have easy stream output and input (<<, >>) that parses the MATLAB format. I'm really just talking about the interactive debugger.
Frank Krueger
GUI interactive debugger that is :-)
Frank Krueger
+2  A: 

VisualStudio has a nifty solution to your problem, AutoExp.dat Obviously this won't help you since you do not appear to be using VisualStudio, but for those using VS they can create custom expressions and even functions to display data in the debugger.

Stephen Nutt
+3  A: 

XCode allows you to create custom data formatters to format the data in the debugger in any way you'd want.

Jasper Bekkers