2014-09-18 38 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