In reviewing the implementation of the WinSTL Registry Library's
winstl::basic_reg_value class - as described in
part 1 and
part 2 of this series of posts - I've also spotted a defect in exception-safety.
Consider the (chopped-down) definition of the
basic_reg_value class:
template < . . . >
class basic_reg_value
{
. . .
private:
hkey_type m_hkey; // The parent key of the value
string_type m_name; // The name of the value
. . . // other members
};
The
m_hkey member is obtained via
winstl::reg_traits<>::reg_dup_key(). It is the
basic_reg_value class itself that provides the
RAII. Consequently, if any exception occur during its constructor, the release of
m_hkey will
not be carried out.
Since the
m_name is a string class instance, its constructor can throw. Consequently,
basic_reg_value is not exception safe.
Thankfully, the fix is very simple. Simply reverse the order of declaration of the two members. If
m_name's constructor throws, that'll happen
before the key duplication takes place. If the key duplication throws an exception, the (fully constructed)
m_name's destructor will be invoked. Q.E.D.