SafeInt Compiles on gcc!

[update 12-1-08] I now have it completely compiling on gcc, with a test harness that exercises every method of the class for every combination of types (all 15 of them). Version 3.0.12p is now moved to release status.

 Once I got SafeInt posted on CodePlex, Niels Dekker grabbed a copy and started figuring out what needed to be done in order to get SafeInt to compile using gcc. Niels was one of the first people to give me bug reports during the development of SafeInt 1.0.x, and he's been extremely helpful over the years – hard to believe I've been working on SafeInt for 5 years now. When we first tried to compile it with gcc, gcc didn't have the template support that SafeInt needed – it was a complete mess, and we gave up quickly – about as bad as trying to get it to compile using Visual Studio 6.

As it turns out, I'm also working on updating the "19 Deadly Sins of Software Security" – there's going to be 2 dozen sins this time around, and I set up a Linux system so I can test things. I originally started running Linux in 1993 – I think it was version 1.0.3, and have tried to keep one running for most of the time since. Having a Linux system handy, I also had g++ available, and I could then actually test some of the issues Niels pointed out – and found a couple more – seems that gcc on cygwin != gcc on Linux. It took about 3-4 hours, but since Niels had already pointed me in the right direction, it went much more quickly than if I'd had to puzzle it out completely by myself. Seems that gcc is a little stricter about some things than Visual Studio, and some of this is a very good thing.

Here's an example of an insidious issue I'd never given much thought to – say you had some function with the following signature:

void Foo(unsigned int& cch);

If you passed it some argument, you would expect it to get modified, right? That's what references are for. Now let's say you called it like so:

unsigned int x;
Foo((unsigned int)x);

Would the cast change anything? How about if we did this?

void Foo(bar_class& cch);

bar_class x;
Foo((bar_class)x);

As it turns out, the cast creates a temporary copy, and the temporary copy _might_ be the one that gets modified. The Visual Studio compiler will do the right thing if you're dealing with a native type – like unsigned int – and go ahead and discard the cast and modify the argument as you'd expect. Unfortunately, if it is not a simple type (haven't tested with things like simple structs), it is the temporary copy that gets modified, and the argument does not. The most recent released Visual Studio compiler doesn't even complain about this >8-O OTOH, the gcc compiler does, and while it wasn't a runtime bug in SafeInt, it was non-standard C++, and it's now fixed in the 3.0.12p line.

A gcc issue that I think is not a bad thing for Visual Studio is in the area of implied template parameters – say you did this:

template <typename T, typename U> class Foo {
template <typename T> void FooMethod(){ Bar:: foo<U>();}
};

You'd expect the U parameter to be the same as the enclosing class, and with the Visual Studio compiler it is – but gcc complains. In order to fix it, you have to use 'template' keywords, like so:

template <typename T> void FooMethod(){ Bar::template foo<U>();}

Despite Niels pointing me to a helpful page, I'm still not sure why the template keyword is really anything helpful. Maybe someone reading this can illuminate me on the topic.

Some of you may be wondering why I care about SafeInt on gcc – after all, I do only really write code for Windows, and have for a long time. The first reason I care about this is that I'd like it if SafeInt were something that could be used by people writing cross-platform code – a lot of our customers do this, and if I can eliminate one more reason to have to fork code (or not use SafeInt), that would be nice. The second reason is that we do have quite a few people developing for MacOS here – MacOffice is the biggest example, and Apple for some reason requires gcc to compile. It would be really nice if we could use SafeInt on all of our code, not just Windows code.

If you'd like to check out a version of SafeInt that does compile on gcc, you can get it here - https://www.codeplex.com/SafeInt/Release/ProjectReleases.aspx?ReleaseId=19785

I've also included the start of a public test harness for the class, which isn't complete just yet – which is why this release is marked planned, not released.