Reputation: 12811
As I understand it, VariantChangeType
is supposed to correctly detect overflows and return DISP_E_OVERFLOW
if an overflow occurs. However, I have found at least one case where this does not occur. Does anyone have any insight into this? I am using Windows 7, VS2013, VC++2008.
VARIANT v;
VariantInit(&v);
v.vt = VT_UI2;
v.uiVal = 32768;
HRESULT hr = VariantChangeType(&v, &v, 0, VT_I2);
With the code above, I would expect that hr
would be equal to DISP_E_OVERFLOW
. However, S_OK
is returned from VariantChangeType
and the value of the VARIANT v
is -32768
(exactly what I expect from 16-bit integer overflow).
Upvotes: 4
Views: 1671
Reputation: 941970
Think of this the other way around. What if you wanted to create scripting language that does support conversions like this? Not uncommon, C# and C behave this way for example. If VariantChangeType() would disallow this then you couldn't implement this conversion.
You can get an overflow if you need it. You must convert to VT_UI4 first, then to VT_I2. That fails with a values 32768 and up.
Upvotes: 3
Reputation: 597016
The documentation for VariantChangeType()
states:
DISP_E_OVERFLOW
The data pointed to by pvarSrc does not fit in the destination type.
If the conversion from VT_UI2
to VT_I2
succeeds for 32768, that suggests to me that a VT_UI2
value fits in a VT_I2
, even if it wraps to a negative value.
Let's say the variant held a VT_UI4
instead. If the value were > 32767, that could not be converted to VT_I2
, and should report DISP_E_OVERFLOW
.
On the other hand, the documentation for VarI2FromUI2()
says the same thing for DISP_E_OVERFLOW
, and VarI2FromUI2()
actually does fail with DISP_E_OVERFLOW
for an input value of 32768.
So that would suggest that VariantChangeType()
is either broken for this conversion, or it is using a different set of conversion rules, maybe for legacy reasons.
Upvotes: 4