Stop energy vs Forward motion
August 5th, 2004Miguel de Icaza wrote :
Most people operate in Stop Energy mode, so I typically ignore them, and keep moving.
and provides a link to this funny article defining what "Stop Energy" is.
I find this idea really relevant for social life or any kind of project you'd start, and especially relevant when you write software.
I'd like to hear from other people : what kind of Stop Energy are you meeting in your work and which forms does it take ? (new tools/technologies adoption for instance, any change in the way we work?)
C++ unit testing with TUT
August 4th, 2004I spent some days working on a project which targets native Win32, Solaris, and other *nixes in pure C++ (no .Net this time), and wanted to write a few units tests to fix bugs I was meeting in ooold libraries.
I went fishing for a portable unit testing framework for native c++ and met TUT (apart from the more well known boost::test and cppunit, but I found TUT more lightweight and easy to setup).
It's convenient to use and elegant, though it requires a "strongly template compliant compiler" : VS.Net 2003 and GNU GCC 2.95+ are fine, but VS.Net 2002 should not work according to the FAQs.
Setup is easy (2 include files, and a simple test runner, provided in the examples). TUT relies on templates and supports setup/teardown through a data structure shared amongst the testcases. Here's an example test :

note : sorry for the image post, didn't find a decent way to post c++ code yet
notebis : code is partially written from my souvenir and may not compile
Writing new tests is fun and comfortable. The design of the framework is nice as well; the notifier for test results is decoupled from the test runner itself, which allows to write custom notifiers (eg: an XML logger for continuous integrations).
Apart from an automated build process, in IDE's which support post build events such as VS.Net, I found it nice to trigger tests execution after the build, to make the build fail if one of the tests fails (so that anyone trying to build the project is aware of unit tests state).
In VS.Net for instance, I've modified the testrunner with this at the end to match the format the external tools are supposed to follow :

and I've set the post-build event of the test project to "$(TargetPath)". This macro expands to the test project executable absolute path, which will be then run on successful builds; any test failure will then trigger build failure.
Ok now, back to NUnit :D
Managed C++ survival kit
July 25th, 2004Writing C++ libraries with VS.Net is not as smooth as expected... Here are a few resources which have proven useful :
* PRB: Linker Warnings When You Build Managed Extensions for C++ DLL Projects
* What are the C and C++ libraries my program would link with ?
Added (30/09/2004) :
* How To Convert from System::String* to Char* in Visual C++ .NET
Added (01/10/2004) :
* BUG: AppDomainUnloaded Exception When You Use Managed Extensions for C++ Components
The long run
July 23rd, 2004About integer types used as keys in a Hashtable.
What do you think will happen if you do write this in C# ?:
Hashtable table = new Hashtable();
int intKey=50;
long longKey=50;
table.Add(intKey,"SomeValue");
table.Add(longKey,"SomeValue");
int count = table.Count;
When one adds a key which is already in a Hashtable, (s)he hopefully gets an ArgumentException.
In our case, no exception will be actually thrown, and the table will count 2 items, which can be far away from what you've been expecting.
What's happening behind the scene.
Hashtable relies on its protected method KeyEquals(object,object) to compare keys, for instance when you Add() an item.
As stated in the documentation:
* KeyEquals uses object.Equals(key) to compare keys, unless the Hashtable was created with a specific IComparer
* System.Int32.Equals(object) will return true only if object is an Int32 itself (so a long/Int64 won't match this requirement) AND the value of the int is the same
* the same remark applies to System.Int64.Equals()
In the above example, KeyEquals(longKey,intKey), if invoked, will return false; as we didn't provide a specific IComparer, the comparison is based on System.Int32 and System.Int64 Equals() methods, which inform the Hashtable the two keys are different.
Going Managed C++.
One of my team's member, writing a managed c++ wrapper around existing classes, was adding items to a hashtable with code similar to this one :
long orderid = ....;
table->Add(__box(orderid),anOrder);
Later from a C# app, we expected to get the order back from the Hashtable :
long orderid=...;
Order anOrder = table[orderid] as Order;
What's wrong with this ?
C++ long is 32 bits, not 64, so it gets boxed into a System.Int32. In C#, long is System.Int64, so you never find your order back, as I explained earlier.
Conclusion.
IMHO, it's better to avoid using integer types as keys for a Hashtable as it is error prone.
For any reason, should I have to use integer type as a key, I'd think about defining a custom (possibly value) type to be used as key, which would wrap whatever integer object is appropriate.
This approach, while providing a stronger typing and a better encapsulation, won't cost more memory.