Refactoring with References and Pointers Tip

Inherited source code is a fact of life for any professional programmer.  Sometimes you inherit a 5000+ line C++ method chock full of pointers and pointers to pointers.

If you’re utilizing the copy-and-paste algorithm for refactoring large blocks of pointer and pointer-to-pointer riddled code then C++’s Pass by Reference support can make these changes much less painful.  Thankfully it supports References to Pointers!

So instead of taking a block similar to the following:

int *ptr = NULL;

if ( someCond )
ptr = new int[len]; // we either allocate it here or leave it null

for (int i=0; i < len; i++)
{
if ( ptr == NULL )
{
ptr = new int[len];
}
else
{
delete [] ptr;
ptr = new int[len + i];
}

int x = ptr[i] * ptr[i + 1];
// ... several hundred lines of code
}






and converting the loop into something unreadable, error prone and barely recognizable as the former loop body:




void SomeFunc(int** ptr, int len)
{
for (int i=0; i < len; i++)
{
if ( (*ptr) == NULL )
(*ptr) = new int[len];
else
{
delete [] (*ptr);
(*ptr) = new int[len + i];
}

int x = (*ptr)[i] * (*ptr)[i + 1];
// ... several hundred lines of code
}
}





You can convert the loop into something easily recognizable as the former loop ala:




void SomeFunc(int*& ptr, int len)
{
for (int i=0; i < len; i++)
{
if ( ptr == NULL )
{
ptr = new int[len];
}
else
{
delete [] ptr;
ptr = new int[len + i];
}

int x = ptr[i] * ptr[i + 1];
}
}



Intervals, Interval Boundaries and Pixels

Anyone working as a computer programmer has at some point had to precisely distinguish between intervals and interval boundaries.

Intervals are delimited by interval boundaries.  For instance, 1-2 denotes a single interval.  In this case the interval is delimited by 2 interval boundaries (1 and 2).

There are always 1 more interval boundaries than there are intervals (since intervals are closed).

A similar relationship can be seen in languages that index arrays/collections from 0.  The total number of elements (or count) in an array is 1 greater than the number of indices.

Having recently worked on drawing lines on 2D surfaces with DirectX I’m beginning to think of pixels as intervals and vertices as interval boundaries.

RECT in GDI vs DirectX

In GDI the right and bottom edges of a RECT are adjacent to the region being specified by the RECT.  So the right most pixel in the region will be at RECT.X – 1.

DirectX also uses RECTs to designate rectangular regions.  Does DirectX follow the same convention as GDI with respect to the exclusivity of the right and bottom edges?  From some preliminary testing I’d say no – RECTs are inclusive along all edges in DirectX.  I’ll need to do more testing to be sure of this.