Search code examples
c++winapivisual-c++comvariant

VariantChangeType and overflow


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).


Solution

  • 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.