Reminder: When a C++ Object Fails to Construct, the Destructor Does Not Run -- Raymond Chen

RaymondChen_5in-150x150.jpgIn C++, if an object’s constructor fails (due to an exception), destructors are run for the object’s member variables and base classes, but not for the object itself. The principle at play is that you cannot destruct something that was never constructed in the first place.

Reminder: When a C++ Object Fails to Construct, the Destructor Does Not Run

by Raymond Chen

From the article:

Consider this pull request:

com_timeout_t(DWORD timeoutInMilliseconds)
    : m_threadId(GetCurrentThreadId())
{
    m_cancelEnablementResult = CoEnableCallCancellation(nullptr);
    err_policy::HResult(m_cancelEnablementResult);
    if (SUCCEEDED(m_cancelEnablementResult))
    {
        m_timer.reset(CreateThreadpoolTimer(
            &com_timeout_t::timer_callback, this, nullptr));
        err_policy::LastErrorIfFalse(
            static_cast<bool>(m_timer));
        if (m_timer)
        {
            FILETIME ft = filetime::get_system_time();
            ft = filetime::add(ft, filetime::
                    convert_msec_to_100ns(timeoutInMilliseconds));
            SetThreadpoolTimer(m_timer.get(), &ft,
                    timeoutInMilliseconds, 0);
        }
    }
}

~com_timeout_t()
{
    m_timer.reset();

    if (SUCCEEDED(m_cancelEnablementResult))
    {
        CoDisableCallCancellation(nullptr);
    }
}

⟦ member variables: ⟧

HRESULT m_cancelEnablementResult{};
DWORD m_threadId{};
bool m_timedOut{};
wil::unique_threadpool_timer_nocancel m_timer;
The idea is that the constructor first calls Co­Enable­Call­Cancellation and reports the failure via err_policy::HResult().

Add a Comment

Comments are closed.

Comments (0)

There are currently no comments on this entry.