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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With