Home on the range

Code, CodeProject

Continuing on the train of thought started in bounds class I presented a few days ago in Bounds, and staying within them.

As so often happens, just having bounds available made me think of what variants of it could be useful. For instance, it would be handy to have it work for floating point or non-POD types, which isn’t possible as it is written. Since the bounds class uses ‘non-type template parameters‘ for its limits, only integer types and enums are accepted.[1]

Even disregarding this restriction, I found that I had use for a dynamic range class, as opposed to the static bounds which has its boundaries set at compile time. Just a simple one, and like std::pair only having two values, but with both of the same type, and with them guaranteed to be ordered.

The last part there would make it a bit more complex than the simple std::pair struct, as I’d need to validate the values given in order to ensure that the minimum was lower than or equal to the maximum, but still, a simple enough little class.

Advertisements

Old bag of tricks

Meta

The main reason for starting this blog was to serve as an incentive to do some long-overdue tidying. Like pretty much any programmer who’s been working for a few years, I’ve got a little bag of tricks I’ve been carrying around throughout my career (17 years so far, of mainly C++, Delphi, and C#). Over the years, some bits and bobs have become obsolete (like that string class I wrote back in 1993, and everything I’ve ever written in Visual Basic), others have been lost in transitions and moves, but it’s still a sizeable bag.

Most of the things in the bag, though, has been unorganised little snippets of code, random functions and classes that have been half-formed, often neither tidy or documented enough to be presented publicly. Some has come from experiments and trials, some from various hobby projects, and some from times my work contract has given me some rights to the software I write.

The last part there is a sensitive area. In most employment contracts, the employer retains the full right to the code you write as part of your job. If you are an independent contractor, the rights issue can be more flexibly negotiated, and there’s sometimes a distinction made between business-related code, and supporting code.

In most cases, the code I’ve written in my day job is code I have no rights to. But because I’m a geek, I’ve sometimes thought “Oooh, that’s interesting”, and sat down to try out and experiment with some concept in my spare time. In those cases, the inspiration might have come from my day job, but the code has been written in my spare time, from scratch. It may be because I’ve wanted to learn more, or because it’s been an interesting problem to solve, or simply because the day job has only required a partial, specialised solution, so I’ve wanted to do a full solution for my own intellectual satisfaction.

It’s often been the case, too, that I’ve found a use for these little snippets later, for a different employer, and in those cases I’ve taken my old code and tweaked or rewritten it to fit into the style and needs of the current workplace.

So I finally decided to tidy things up. I’ll be re-visiting my old code folders, and extract what’s useful or interesting, and tidy it up, and package it. I will:

  • stick to a single style of coding (per language) and rewrite the code to have a consistent look
  • organise the code into namespaces and classes
  • comment the code thoroughly
  • use Doxygen or similar to extract the comments to useful documentation
  • write a simple test app to exercise the code for each module
  • for each module, create packages with:
    • only source code
    • source code, documentation, and example/test app
  • release under a BSD license

Why? Well, in a large part to make it easier for me to find, and introduce at the places I work. And I also think other people might find these bits and bobs useful.

I wonder, though, whether it would also be useful to make the code available on SourceForge and/or CodeProject?

Static assert in C++

Code, CodeProject

Just a quick little note today, to clarify something I mentioned in passing the other day in Bounds, and staying within them. I said I “I added a static assert to validate the template parameters at compile time”, and it’s probably worthwhile to spell out how that works for those who haven’t seen it before.

As a rule, the earlier you find an error, the easier it is to identify and fix. The errors spotted by your compiler are, naturally, easier to fix than the errors exhibited by your program as it is running. A static assert helps by letting you sanity-check the code you write, and generating a compiler error if you write code that is syntactically correct, but logically incorrect.

For instance, the bounds class takes a lower and upper boundary as template parameters, and assumes them to be ordered. Say we didn’t have a static assert, and used it to find out if a randomly generated world in a space game is suitable for colonisation, and what animals can be introduced.

typedef bounds<int, -5, -30> polarbear_temp;
...
// generating a randomworld and it's temperature
...
// Adding various animals
if (polarbear_temp::in_bounds(randomworld_temp))
...

This would lead to a universe completely devoid of polar bears (which I’m sure we all can agree would be a bad thing), because there is no temperature that can be both greater than -5 and less than -30.

Because the limits are known at compile time, it makes sense to check them at compile time, too.

Bounds, and staying within them

Code, CodeProject

How often have you written a line of code that looks something like this?

if (3 <= var && 14 >= var)

There might (read “should”) be named constant variables instead of the magic numbers there, but in essence it’s a very common piece of code for a very common type of test – is this value within pre-defined, constant bounds?

Some years ago, I was working on a project that had lots of tests like that, and I came across a surprisingly large number of errors one can commit with this simple code. For instance:

// non-paired constants
if (minTempUK <= var && maxTempUS >= var)

// wrong comparison 
if (minTempUK < var && maxTempUK >= var)

// test wrong way around  
if (maxTempUK <= var && minTempUK >= var)

// maxTempUK is compared to bool  
if (minTempUK <= var <= maxTempUK)

// bitwise rather than logical AND    
if (minTempUK <= var & maxTempUK >= var)  

All of these are legal C++, and only the last two or three might generate compiler warnings. The last would still work properly, but is a bit iffy. If it isn’t a typo, someone needs to read up on operators. In most cases, these errors were typos (except the fourth, which was written by someone more used to other languages), but since they compiled, and sort of worked, they only showed up as bugs every now and then, at the edge cases. And because the code looks sort of okay, it was hard to spot the typos right away.

Redux: RAII adapter for Xerces

Code, CodeProject

In my previous entry, C++ RAII adapter for Xerces, I presented a simple memory management wrapper for Xerces types. Because of the way Xerces manages memory, I said, the quite handy boost::shared_ptr couldn’t be used, so I wrote the memory management code myself to produce a safe wrapper in the style of std::auto_ptr.

However, as Alf P. Steinbach pointed out, I was wrong, in that boost::shared_ptr could be used by taking advantage of the custom deleter facility offered by that class. One benefit is that I can get rid of my hand-rolled memory management, but on the other hand, I’ll have to adjust the public interface to reflect different semantics.

C++ RAII adapter for Xerces

Code, CodeProject

Xerces is a powerful validating XML parser that supports both DOM and SAX. It’s written in a simple subset of C++, and designed to be portable across the greatest possible number of platforms. For a number of reasons, the strings used in Xerces are zero-terminated 16-bit integer arrays, and data tends to be passed around by pointers. The responsibility for managing the lifetime of the DOM data passed around is usually Xerces’, but not always. Some types must always be released explicitly, while for others, this is optional.

In other words, this is a job for the RAII idiom. Alas, we can’t reach for our boost::shared_ptr[1] or std::auto_ptr, since Xerces has its own memory manager, and when Xerces creates an object for you, it is not guaranteed to be safe to simply call delete. Instead, you must call the object’s release() function.