2014-09-18 37 views
4

据我所知,VariantChangeType应该是正确检测溢出并返回DISP_E_OVERFLOW如果发生溢出。但是,我发现至少有一个情况不会发生。有没有人对此有所了解?我正在使用Windows 7,VS2013,VC++ 2008。VariantChangeType和溢出

VARIANT v; 
VariantInit(&v); 
v.vt = VT_UI2; 
v.uiVal = 32768; 
HRESULT hr = VariantChangeType(&v, &v, 0, VT_I2); 

通过上面的代码,我预计hr将等于DISP_E_OVERFLOW。但S_OKVariantChangeType返回和的值是-32768(正是我期望从16位整数溢出)。

回答

4

documentation的用于VariantChangeType()状态:

DISP_E_OVERFLOW
数据通过pvarSrc指向不适合在目标类型。

如果从VT_UI2VT_I2转换成功为32768,这表明,我认为一个VT_UI2值在VT_I2适合,即使换到负值。

让我们假设该变体代替VT_UI4。如果值大于32767,则不能转换为VT_I2,应该报告DISP_E_OVERFLOW

在另一方面,对于documentation说:VarI2FromUI2()DISP_E_OVERFLOW同样的事情,并VarI2FromUI2()实际上并失败,DISP_E_OVERFLOW为32768

的输入值,因此,这将表明,VariantChangeType()是这种转换要么破,或者它正在使用一组不同的转换规则,可能出于传统原因。

+2

+1。这种差异对我来说似乎是一个(20岁)的错误。 – 2014-09-19 07:51:10

+0

经过多次辩论后,我会给出这个答案。在下面看到我对@Hans的评论。 – 2014-09-22 15:23:09

3

想想另一种方式。如果你想创建支持像这样的转换的脚本语言?并不少见,例如C#和C就是这样表现的。如果VariantChangeType()会禁止这个,那么你不能实现这个转换。

可以如果你需要它会得到溢出。您必须先转换为VT_UI4,然后转换为VT_I2。这失败了值32768及以上。

+0

经过一番辩论之后,我会给@Remy答案。你的观点当然不是没有道理的。然而,我认为它更像这样:VariantChangeType可以做一些事情,比如将字符串转换为日期。这是一种语义转换,而不是位级转换。我认为这种功能的最佳设计应该是完全以单向或完全相反的方式工作。我相信VariantChangeType的真正意图是语义转换。因此,我认为这是一个错误或一个设计缺陷。 – 2014-09-22 15:22:41

+0

从*语义*的角度来看,它很可能是有道理的,一个无符号32768转换为一个带符号-32768没有错误。很多的Win32 API的区域取决于传递一个符号整数反之亦然-1,其中无符号整型值预期,与邪恶。因此,至少在相同大小的转换,也许对所有转换,VariantChangeType的'的行为()'可能是故意的,尽管无证。 – 2014-09-22 16:07:35