这是 ATL::CComVariant 中的自分配错误吗?
ATL::CComVariant
具有 一些赋值运算符。我在实现中看到的是,在接受 LPCOLESTR 、 IUnknown* 或 IDispatch* 的赋值运算符中,第一个操作是调用 Clear ()。
如果以传递同一对象的成员变量的方式调用运算符
CComVariant variant;
variant = L"string";
variant = variant.bstrVal;
(有更少愚蠢的方法可以达到相同的效果)Clear()
将释放封装的对象和所有对现在悬空指针的后续操作将导致未定义的行为。
我是正确的还是我误解了什么?
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 actions on the now dangling pointer will result in undefined behavior.
Am I correct or have I misunderstood anything?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个错误。
不幸的是,ATL 仍然有相当多的此类内容 - 比我在任何其他具有类似影响力的图书馆中处理过的内容都要多。
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.
由于 CComVariant 实例管理字符串指针,此类赋值的预期逻辑是类实例复制字符串并初始化内部成员(类型和字符串指针)。当前拥有的价值/资源被处置。
如果我们将拥有的指针作为参数传递,我们有兴趣确保在释放成员值之前该值是重复的。或者,该方法正确检测“相同指针”情况并忽略赋值。从 Visual Studio 2015 Update 3 开始,ATL 正是这样做的:它检测相同的指针分配并立即返回,跳过分配/释放部分。也就是说,ATL 实现是准确的并且可以很好地处理这个问题。
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.