Edit
Attach
Printable
topic end
<!-- * Set TOPICTITLE = Claus Brod: Beware of unknown enumerators (26.1.2006) --> <style type="text/css"> pre {background-color:#ffeecc;} </style> %STARTINCLUDE% <a name="26"></a> ---+++ [[BlogOnSoftware20060126][Beware of unknown enumerators]] (26.1.2006) The other day, I was testing COM clients which accessed a collection class via a COM-style enumerator (=IEnumVARIANT=). And those clients crashed as soon as they tried to do _anything_ with the enumerator. Of course, the same code had worked just fine all the time before. What changed? In COM, a collection interface often implements a function called =GetEnumerator()= which returns the actual enumerator interface (=IEnumVARIANT=), or rather, a pointer to the interface. In my case, the signature of that function was: <pre> HRESULT <nop>GetEnumerator(IUnknown **); </pre> Didn't I say that =GetEnumerator= is supposed to return an =IEnumVARIANT= pointer? Yup, but for reasons which I may cover here in one of my next bonus lives, that signature was changed from =IEnumVARIANT= to =IUnknown=. This, however, is merely a syntactic change - the function actually still returned =IEnumVARIANT= pointers, so this alone didn't explain the crashes. Well, I had been [[BlogOnSoftware200512#FingerPointingAtSmartPointers][bitten before by smart pointers]], and it happened again this time! The COM client code declared a smart pointer for the enumerator like this: <pre> CComPtr<IEnumVARIANT> enumerator = array->GetEnumerator(); </pre> This is perfectly correct code as far as I can tell, but it causes a fatal avalanche: * The compiler notices that =GetEnumerator= returns an =IUnknown= pointer. This doesn't match the constructor of this particular smart pointer which expects an argument of type =IEnumVARIANT *=. * So the compiler looks for other matching constructors. * It doesn't find a matching constructor in =CComPtr= itself, but =CComPtr= is derived from =CComPtrBase= which has an undocumented constructor =CComPtrBase(int)=. * To match this constructor, the compiler converts the return value of =GetEnumerator()= into a =bool= value which compresses the 32 or 64 bits of the pointer into a single bit! (Ha! <nop>WinZip, can you beat _that_?) * The boolean value is then passed to the =CComPtrBase(int)= constructor. * To add insult to injury, this constructor doesn't even use its argument and instead resets the internally held interface pointer to 0. Any subsequent attempt to access the interface through the smart pointer now crashes because the smart pointer tries to use its internal interface pointer - which is 0. All this happens without a single compiler or runtime warning. Now, of course it was our own silly fault - the =GetEnumerator= declaration was bogus. But neither C++ nor ATL really helped to spot this issue. On the contrary, the C++ type system (and its implicit type conversions) and the design of the ATL smart pointer classes collaborated to hide the issue away from me until it was too late. %COMMENT{type="below" nonotify="on"}% --- %STOPINCLUDE%
to top
End of topic
Skip to action links
|
Back to top
Edit
|
Attach image or document
|
Printable version
|
Raw text
|
Refresh
|
More topic actions
Revisions: | r1.1
|
Total page history
|
Backlinks
You are here:
Blog
>
BlogOnSoftware20060126
r1.1 - 17 Feb 2006 - 06:47 -
ClausBrod
to top
Blog
This site
2017
:
12
-
11
-
10
2016
:
10
-
7
-
3
2015
:
11
-
10
-
9
-
4
-
1
2014
:
5
2013
:
9
-
8
-
7
-
6
-
5
2012
:
2
-
10
2011
:
1
-
8
-
9
-
10
-
12
2010
:
11
-
10
-
9
-
4
2009
:
11
-
9
-
8
-
7
-
6
-
5
-
4
-
3
2008
:
5
-
4
-
3
-
1
2007:
12
-
8
-
7
-
6
-
5
-
4
-
3
-
1
2006:
4
-
3
-
2
-
1
2005:
12
-
6
-
5
-
4
2004:
12
-
11
-
10
C++
CoCreate Modeling
COM & .NET
Java
Mac
Lisp
OpenSource
Scripting
Windows
Stuff
Changes
Index
Search
Maintenance
Impressum
Datenschutzerklärung
Home
Webs
Atari
Blog
Claus
CoCreateModeling
Klassentreffen
Main
Sandbox
Sommelier
TWiki
Xplm
Jump:
Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback