More On IDisposable

C# No Comments »

My posts Deterministic Finalization in Garbage-Collected Languages and Rules for Implementing IDisposable are, in my opinion, a fair introduction to the purpose and use of C#’s IDisposable idiom. However, I would like to propose the following additional guideline for the usage of IDisposable:

The class which creates a disposable object is responsible for calling Dispose().

Ridiculously obvious, right? Yet it has some important implications. Consider this quote from Rules for Implementing IDisposable:

If you write a class which contains a member which implements IDisposable, your class must also implement IDisposable and dispose each member in turn in your Dispose() method.

This is only true if your class created the disposable object. If your class was passed the disposable object in the constructor, you should not call its Dispose() method. Similarly, if you are writing a class which wraps a Stream and provides additional functionality (e.g. BufferedStream or GZipStream), you should not call the underlying Stream’s Dispose() method if you did not create the underlying Stream yourself.

This implies that, in general, passing an object to a constructor of another class is not a transfer of ownership. (For further reflection: Are there cases where this isn’t true? Is there an alternative idiom to express the concept of transfer of ownership?)

Statistical Misuse

Statistics No Comments »

One of my favorite columns in The Wall Street Journal is “Ahead of the Tape”, which is typically in the left column of page C1 of the print edition. Unfortunately, Mr. Whitehouse made a rather silly mistake today. Consider the following passage:

Yet from a statistician’s point of view, the market’s reaction to the [Labor Department's monthly jobs report] is hard to fathom. Over the past six years, the economists’ consensus has missed the reported number, on average, by about 82,000 jobs, according to Bianco Research. That might look like a big difference. But as a percentage of total payroll employment — 135 million — it’s actually very small, less than one tenth of 1%.

Measuring the employment change forecast miss as a percentage of total employed isn’t appropriate. The reason why is that the total payroll employment figure changes relatively little from month to month — a smashing increase of 400,000 jobs in a month is only a 0.3% change.

To illustrate, let’s say the average temperature of the core of the sun is 15,000,000 K and the standard deviation of temperature is 1,000 K. This means that 99.6% of the time the temperature will be between 14,997,000 K and 15,003,000 K. If your forecast is off by 0.1% of the average temperature (15,000 K) it is absurd!

A better method to estimate prediction accuracy is to compare prediction error (probably the root mean squared error) to the standard deviation of the distribution. No doubt that there are better methods yet.

Mutt libESMTP Patch Version 4

Mutt No Comments »

After a long time without making any changes, I have finally added TLS support to my libESMTP patch for mutt. Thanks to Shaun Eack at Wolfram for providing the initial patch.

C++, STL, DLLs, and Buggy Optimizations

STL No Comments »

Recently a bug in the STL implementation that comes with Visual C++ 6.0 was brought to my attention. Consider the following function:

typedef std::map<std::string, std::string> map_t;

void f(const map_t& map)
{
    for (map_t::const_iterator iter = map.begin();
         iter != map.end();
         ++iter)
    {
    }
}

For Visual C++ 6.0, if you call f() from within the same EXE or DLL, it works fine, but if calling f() requires you to cross an EXE or DLL barrier, it will fail.

After some debugging, I figured out that this bug is because Visual C++ 6.0’s implementation of std::map, which stores data in a tree structure internally, uses a class static variable to represent a NULL tree node. After putting f() in a separate DLL, the std::map class static value gets initialized to one value in the EXE (on a run on my machine, 0x002f1000) and another value in the DLL (on a run on my machine, 0x003127c0). The ++iter line in the DLL leads to a loop which terminates when it encounters a node it thinks is NULL (0x003127c0). However, as the NULL node was set by the EXE, it has the value 0x002f1000, so the loop within the DLL walks off the tree and crashes.

Per Microsoft Knowledge Base Article 172396: You may experience an access violation when you access an STL object through a pointer or reference in a different DLL or EXE, this is a problem that’s fairly endemic across all of VC++ 6.0 when using STL objects across DLL/EXE barriers. The reason is Microsoft’s STL implementation used class static variables in a number of places to try to avoid storing multiple copies of the same information, but they did not anticipate this DLL-related problem. By the way, this bug is reportedly fixed in Visual C++ 7.

The KB article has a number of suggested workarounds, but I don’t like any of them. Dinkumware, who wrote the Visual C++ 6.0 STL library, has provided a xtree header replacement which fixes the bug by making the value of NULL tree nodes a member of the class rather than a class static variable as part of their Fixes for Library Bugs in VC++ V5.0/V6.0 page, but I don’t like the idea of using third-party compiler header replacements.

My recommendation is to avoid passing STL objects as parameters to DLLs. I also suggest being very careful about using class static variables in your own code.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in