Category Archives: Programming

[c++] Static assertions – Part III

For completeness let’s look at the static_assert keyword introduced as part of C++0x. Picking up where the previous two posts (I & II) left off (in 2008!).

int main( ) {
    static_assert( false, "This must be true" );

    return 0;
}

Visual Studio 2010 outputs:
1>main.cpp(2): error C2338: This must be true

Hooray for progress!

A static assertion that outputs a user controlled error message. Making it much easier to indicate what the actual problem is, and avoiding the need to dig through large amounts of invalid and/or undefined type related compiler output mess.

Better yet; BOOST_STATIC_ASSERT will take advantage of static_assert if your compiler supports it.

#include <boost/static_assert.hpp>

#pragma pack( push, 1 )
struct PktData {
    char b1;
    char b2;
};
#pragma pack( pop )

BOOST_STATIC_ASSERT( 1 == sizeof(PktData) );

Visual Studio 2010 outputs:
1>main.cpp(10): error C2338: 1 == sizeof(PktData)

Where the error message is populated by the failing expression. Which may be nicer than having to specify your own error message as required by static_assert.

Home Media Server

A while ago I purchased an HP Home Media Server as an external storage device for backups and other files. I really like the form factor and how it has a decent CPU. Most NAS boxes are crippled by their processor which severally limits network throughput. Not so with this guy.

There are many reviews out there saying how great this thing is. Hyping the merits of WHS (Windows Home Server) and the whole backup architecture. Some even proclaiming it has saved their marriage.

I admit that WHS is a cool concept, and for general home users it is great. More advanced users have even gone as far as creating custom add-ons that extend the original functionality. Then there are users such as myself who want even more control; so end up just installing Linux on the thing.

“WHY?” I hear you scream. “Why would someone want to replace the existing operating system that is purpose built for the box, and replace it with a harder to use system?”

Control. Being able to easily control which software is installed and what services are provided. This means my server now boots to a network ready file serving state in under twenty seconds. This would easily take over a minute if not more with WHS. Then again most users would leave their server running all the time. But we’ve already established that I’m not most users…

Biggest problem to installing Linux on the MediaSmart server is that it doesn’t actually have a VGA/DVI/HDMI/display port. So you can’t even see what you are doing. Thankfully ymboc on mediasmartserver.net broke out an oscilloscope and worked out how to wire up a VGA port. Which is why you can see a VGA connector on the front of my server (pictured).

Everything else pretty much works out of the box. Except for the front LEDs. One of which blinks annoyingly at full brightness. This of course drove me nuts and I ended up writing a little utility to control them all.

Source for that Linux LED control utility can be found on bitbucket.

Bacteria v0.21

Just discovered that multiple monitors weren’t being drawn to correctly when arranged with negative coordinates. If you are having trouble with that, try the newer v0.21 version.

Apologies :-/

Bacteria v0.20

Just released a new version of Bacteria.

  • Support a world of Bacteria per monitor (as requested by Zarek)
  • Completely overhauled Bacteria intelligence
  • Switched to Anti-Grain geometry for high quality graphics rendering
  • Increased Bacteria size and removed large option
  • Improved Bacteria movement
  • Slight improvements to configuration dialog
  • Statically linked so no more missing DLL errors
  • Many other internal optimizations and improvements

You can download Bacteria v0.20 from my programs page.

Hash

Found another itch that needed scratching. File hashing.

Every now and again I come across the need to calculate the hash of a file. Either to verify its integrity, check a copy routine, or verify a checksum routine. Most solutions to this are overly complicated. So I’ve created a simple command line program called hash.

> hash –-sha1 hash.exe
sha1(hash.exe)= 519e13cb8bb5e28a7fd161594b4e54289042229a

Hash is available from the programs section.

[c++] Static assertions – Part II

Following on from the very quick introduction to static assertions we can now look at how they are actually implemented. Well… how they are currently implemented before C++0x comes along and cleans it all up.

Nicest way to roll your own static assertion is to use C++ templates:

template <bool B>
struct StaticAssertion;

template <>
struct StaticAssertion<true> { };

#define STATIC_ASSERT( x ) StaticAssertion<x>( )

First we forward declare a class template. Then specialise it for the true case. Finally adding a preprocessor macro to tidy up the end user syntax. As we haven’t defined the false case, the compiler will issue an error if it ever tries to instantiate it.

int main( ) {
    STATIC_ASSERT( false );
   
    return 0;
}

Visual Studio 2008 outputs:

1>main.cpp(11) : error C2514: 'StaticAssertion<B>' : class has no constructors
1>        with
1>        [
1>            B=false
1>        ]

GCC v4.0.1:

main.cpp: In function 'int main()':
main.cpp:11: error: invalid use of undefined type 'struct StaticAssertion<false>'
main.cpp:3: error: declaration of 'struct StaticAssertion<false>'

Both error messages contain the StaticAssertion type and give you the correct line the violation occurred on. From this you can deduce that a static assertion has occurred. Further improvements could be made by the use of additional type parameters to let you know the flavour of the assertion. Which is an exercise left for the reader 😉

Fortunately static assertions are not limited to C++. You can accomplish the same result using straight C.

#define STATIC_ASSERT( x ) sizeof( char[ (x) ? 1 : -1 ] )

This one liner relies on the fact that you can’t declare a negatively sized array.

Visual Studio 2008:

1>main.cpp(11) : error C2148: total size of array must not exceed 0x7fffffff bytes
1>main.cpp(11) : error C2148: total size of array must not exceed 0x7fffffff bytes
1>main.cpp(11) : error C2070: 'char [-1]': illegal sizeof operand

GCC v4.0.1:

main.cpp: In function 'int main()':
main.cpp:11: error: size of array is negative

Error messages still indicate the offending line, but that’s about it. Not as nice as the C++ templated version but the end result is the same. Program fails to compile.

[c++] Static assertions

An assertion statement is used at runtime to verify that an assumption holds true. Typically assert is only used in debug builds, while release builds switch it out completely.

Keep in mind that while an assertion is no substitute for proper error checking, it is useful for a quick verification of low level assumptions. If you design a function with the expectation that the provided pointer will always be valid; then adding an assert will warn the caller when they aren’t playing by the same rules that you are.

int get_nth_char( const char* str, int idx ) {
    assert( str ); // program stops here if str is invalid
    if ( idx < 0 ) return -1;
    return str[ idx ];
}

Static assertions take assert a step further and provide sanity checks at compile time. While static assertions can only operate on known compile time data it is still really useful. A good example is the packing of network data where it is vital that the data is packed correctly and is of the right size. Not only will a static assert verify this. It will also catch the case if it gets changed at a later stage.

#pragma pack( push, 1 )
struct PktData {
    char b1;
    char b2;
};
#pragma pack( pop )

BOOST_STATIC_ASSERT( 2 == sizeof(PktData) );

While the static assert in the above code is courtesy of boost, the upcoming C++0x standard will also include this functionality.

Boost v1.35.0 is out

Boost has released v1.35.0 of their C++ libraries. This includes many great goodies such as asio (asynchronous networking library), bimap (indexable by both the key and value), circular buffer, interprocess (shared memory access), and more.

“Boost provides free peer-reviewed portable C++ source libraries”

http://boost.org

Magnifier

Recently I’ve been doing alot of custom drawing and graphic manipulation. Having been frustrated with other on screen magnifiers I finally went about creating my own solution.

Magnifier

  • Left mouse drag panning
  • Right mouse drag area selection
  • Quick scroll wheel zoom in/out
  • Rough rulers (which you can turn off)
  • RGB pixel value reporting

Magnifier is available from the programs section.