Ancient piece of code started giving troubles:
template <typename T>
class ATL_NO_VTABLE CMediaControlT :
...
{
...
STDMETHOD(Run)()
{
...
T* MSVC_FIX_VOLATILE pT = static_cast<T*>(this); // <<--------------------------------
CRoCriticalSectionLock GraphLock(pT->m_GraphCriticalSection);
pT->FilterGraphNeeded();
__D(pT->GetMediaControl(), E_NOINTERFACE);
pT->PrepareCue();
pT->DoRun();
__if_exists(T::Fire_Running)
{
pT->Fire_Running();
}
...
}
When MSVC_FIX_VOLATILE
is nothing, it appears that optimizing compiler forgets pT
and uses just some variation of adjusted this
, which makes sense overall because static cast between the two can be resolved at compile time.
However, the problem is that the value of this
is wrong and there is undefined behavior scenario.
If I make MSVC_FIX_VOLATILE
to be volatile
and have the variable pT
somewhat “heavier”, optimizing compiler would forget this
and uses pT
directly with everything working as expected.
The problem still exists in current 16.6.2.