Note - Version 3.0.18 is now available as a beta. An updated test harness, and a Visual Studio compatibility header will be available soon. See the 3.0.18 release for notes on what has changed.
Summary - much better support for clang and gcc, also can now be used as a drop-in replacement for the Visual Studio version, which forked from this one at 3.0.12.
Many thanks to Tomasz Kukielka of the Microsoft Office Apex team for pointing out issues with clang, and assisting with code changes.
SafeInt is a C++ header containing the SafeInt class, non-throwing functions to check common operations, and the associated internal mechanisms.
SafeInt is currently used extensively throughout Microsoft, with substantial adoption within Office and Windows. If you are compiling for the Microsoft compiler only, a very similar version is now available with Visual Studio 2010.
It can be used with any compiler that has good template support, and is known to work on Visual Studio 7.1 or later.
Thanks to help from Jeffrey Walton of the OWASP project, we now have a very complete runtime test harness. There's still a couple of files to get posted, but the files we have on the download section contain most of the new work. To avoid confusion, the
test harness is now a different release than the main header.
Also thanks to Jeffrey, we have extended the list of compilers that are supported to:
Microsoft Visual Studio, version 7.1 through the latest.
Reasonably new versions of gcc, including the latest version that will compile for Apple platforms.
The Intel compiler, with some caveats - it doesn't support some of the friend overloads, but does work properly with the runtime checks.
Clang is also now supported.
The most recent version is 3.0.17. The main change between minor versions 15 and 16 is that the Intel compiler will quite vigorously optimize away some of the signed addition overflow checks. Changes have been made such that intermediate calculations are done
with unsigned numbers, and unsigned overflow is defined by the standard, which means the Intel compiler won't optimize them away. There have been instances of the gcc compiler doing the same thing, but this hasn't been demonstrated in SafeInt. As of
this version, there won't be a possibility of the compiler actually removing checks.
Thanks to John Regehr of the University of Utah for noticing that the compiler may also become aggressive about removing things when you attempt to perform a unary negation on a signed number, and that signed number is a compile-time constant with a value of
MIN_INT. I personally have a low opinion of compilers doing this sort of thing - seems like there's an awful lot of code out there with some extremely subtle bugs when compiled with these compilers. Compiler warnings are your friend, and it seems like
the more compilers you have, the better your coverage. As it turns out, Clang will warn about when this might happen, which enabled a more comprehensive scrub of the code than we were able to do in 3.0.16.
The fix for this particular issue is to go ahead and code in a dependency on 2's complement representation of negative numbers - the compiler may remove -x, but it won't remove ~(unsigned)x + 1, which emits the same bit pattern (and the same assembly
Important note - the runtime test harness does catch it when the compiler optimizes away tests. You should compile and run the runtime checks to verify that everything is working properly with your compiler. Note - as of 3.0.17, we have some work to do to update
the runtime tests to account for compile-time constants. We'll get this updated as soon as practical.
In addition, SafeInt now compiles warning-free with all warnings enabled on both latest gcc and the Microsoft compiler. It will still emit a few warnings with the Intel compiler.
Known outstanding work - I have yet to do the work to correctly annotate the class with throw() in the case of an error handler that does something other than C++ exceptions (structured exceptions, terminate the app, etc).