Friday, January 27, 2006

auto_ptr revisited

Hooray! AxCrypt2Go can now display icons for AxCrypt-files (although just the small one right now). Anyway, it's a proof of concept, now I'll have to refactor that code into something I can publish. That's one of the advantages of open source - it can't look too bad, so it has to be fixed. But that's not what I want to write about today, not really. I realized that I was not running the compiler at the highest warning-level (4), but only 3 and that's normally a principle I want to follow. Highest warning level, and treat warnings as errors. This actually led to a good thing today, because I just clarified something a little bit in my mind about how to use std::auto_ptr to the best effect. As it turns out, the compiler will complain about the following construct:

auto_ptr<char> s;
// Do something...
s = auto_ptr<char>(new char[100]);


The reason this is not a good idea is rather subtle, but basically it's due to the fact that the temporary object is not a reference to an object, it's an object, and you can't really make a reference to a temporary object like that. At least it's pretty bad form... It's a similar situation where you can't use a temporary object as a parameter for a non-const reference formal parameter to a function.
The way to do this is of course:

auto_ptr<char> s;
// Do something...
s.reset(new char[100]);


This led to some other code being affected, specifically code where methods had the following type of signature:

auto_ptr<char> Func() {
auto_ptr<char> t(new char[10]);
// Do something to set t to something
return t;
}


This looks neat, and is apparently a good idea to ensure that allocated objects are automatically delete'd as part of the auto_ptr destructor. However, this messes things up in other parts of the code since once again for similar reasons as above.

The resulting pattern rule is:
  • Always return a pointer, not an auto_ptr, when an object is allocated.
  • Never store a pointer, always wrap it in a auto_ptr object when it's kept around for more than passing on in the same statement.
Now we get the best of both worlds, and less things to send up via function return. The above is not guru-level C++, but it helped me to clarify things.

I'm a strong believer in what I call "code policy". Code policy is about formulating rules of coding, a bit like design patterns but more generic small snippets of wisdom accumulated through experience. I use probably 50 - 100 such "code policies" whenever I write code, and it's certainly been extremely useful. It takes the burden out of making many small decisions, and I may start document them for peer review in the future - that could be fun!

No comments:

Post a Comment