This lived up to Steve McConnel's immortal advice in "Code Complete"
to always write the nominal (normal) case first and to only return from a
single point in a function. Unfortunately, I had lots of Releases that were
easy to forget and lots of nested if blocks, which made reading the code
difficult. Luckily, the Releases were easy to take care of with smart pointers,
like so:

ATL's smart pointer class is especially nice, since it has not only a Release
built into the destructor, but also has helpers like CoCreateInstance. Further,
common QueryInterface bugs can be avoided in VC6 because of the new
IUnknown::QueryInterface member function template :

Even so, Steve's advise to write the nominal case first and to only have a
single point of return from a function lead to practically unreadable code, so
it took quite a lot of putting up with nested if statements before I could
force myself to write the following:

Once I did learn to write my code this way, Halleluiah, I had seen the light.
Suddenly, what my code was actually trying to accomplish leapt out at me.
Still, I could improve it. I hated writing all of those if(FAILED(hr)) blocks,
so, inspired by Tim Ewald, I wrote the following macro:

At this point, I'd almost reached nirvana, but being a critic at heart, I still
found room for improvement. I observed that most errors occur at development
time, but I didn't have a good way to track them. When a COM method fails n
levels deep, I wanted to know the file and the line of code.

Luckily, because I was using a macro, I could augment it with the __FILE__ and
__LINE__ symbols and dump the results to debug out using the following:

Not only did a have a complete stack dump of the call failure, but because I
used VC's output format, I could navigate to the offending file and line with a
single press of my F4 key. At this point, I felt an overwhelming feeling of COM
come over me...

You may worry about so drastically violating Steve's two principles, but I
don't. Writing the nominal case first is all about making the true intent of
your code evident to readers. I think it's clear that my HR macro does just
that. Further, having a single point of return from a function is about
maintainability and resource management. Certainly we've achieved a higher
degree of maintainability via readability and expressly allowing multiple
points of return from a function. As far as resource management goes, smart
pointers are but one kind of smart type class that ATL provides and that I
always use when I'm coding in this style (which is all the time). Since smart
types are necessary in the face of C++ exceptions anyway, this technique fits
right in. Enjoy.