Is this a self-assignment bug in ATL::CComVariant?
ATL::CComVariant
has a handful of assignment operators. What I see in the implementation is that in assignment operators accepting LPCOLESTR
, IUnknown*
or IDispatch*
the first action is to call Clear()
.
If the operator in invoked in such a way that a member variable of the same object is passed
CComVariant variant;
variant = L"string";
variant = variant.bstrVal;
(there're less dumb ways that will have the same effect) Clear()
will release the encapsulated object and all the later actio开发者_开发技巧ns on the now dangling pointer will result in undefined behavior.
Am I correct or have I misunderstood anything?
It's a bug.
ATL unfortunately still has quite a few of those - way more than I have dealt with in any other library with a similar reach.
variant = variant.bstrVal;
As CComVariant
instance manages the string pointer, the expected logic with such assignment is that class instance duplicates the string and initializes internal members (type and string pointer). Currently owned values/resources are disposed of.
In case we pass owned pointer as an argument, we are interested in being sure that the value is duplicated before the member value is released. Or, in that the method correctly detects "same pointer" case and ignores the assignment. As of Visual Studio 2015 Update 3, ATL does exactly this: it detects same pointer assignment and returns immediately skipping allocation/release part. That is, ATL implementation is accurate and handles this well.
精彩评论