程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++ Builder 2010集合類的一個BUG

C++ Builder 2010集合類的一個BUG

編輯:關於C++

今天用C++ Builder 2010寫一段小代碼,用到了集合類,可集合運算結果怎麼也不對,排除了其它原因,最後確定應該是集合類源代碼的問題,下面是一段集合類的測試代碼:

enum TTest{tt0, tt15 = 15, tt16 = 16};  
typedef Set<TTest, tt0, tt16> TTests;  
      
void __fastcall TForm1::Button1Click(TObject *Sender)  
{  
    TTests t1 = TTests() << tt15;  
    TTests t2 = TTests() << tt16;  
      
    ShowMessage(t1.ToInt());    // 32768  
    ShowMessage(t2.ToInt());    // 16777216  
}

測試代碼中的集合類變量t1,t2分別定義為第15位和第16位,顯示結果應該分別為32768和65536,t1結果32768是正確的,t2顯示卻為16777216,顯然是錯誤的。

接下來,我用Delphi 2010寫了類似的測試代碼:

type
  TTest = (tt0, tt15 = 15, tt16 = 16);  
  TTests = set of TTest;  
      
procedure TForm1.Button1Click(Sender: TObject);  
var
  t1, t2: TTests;  
begin
  t1 := [tt15];  
  t2 := [tt16];  
  ShowMessage(IntToStr(LongWord(t1)));  // 32768  
  ShowMessage(IntToStr(LongWord(t2)));  // 65536  
end;

而Delphi 2010代碼顯示結果完全正確。

很明顯,C++Builder 2010代碼中的集合類變量t2向左多移了8位,即16777216是第24位置位後的結果。

我調出C++Builder 2010集合類源代碼文件sysset.h,查看了一下其ToInt函數,發現問題就出在這裡,請看源碼中數據定義和ToInt函數代碼:

template<class T, unsigned char minEl, unsigned char maxEl>  
class RTL_DELPHIRETURN SetBase  
{  
protected:  
  unsigned char Data[((((int)(maxEl/8))-((int)(minEl/8))+1) != 3)?  
     (((int)(maxEl/8))-((int)(minEl/8))+1): 4];  
};  
      
template<class T, unsigned char minEl, unsigned char maxEl>  
class RTL_DELPHIRETURN Set : SetBase<T, minEl, maxEl>  
{  
      
  ......  
      
  int __fastcall ToInt(void) const
  {  
#pragma option push -w-inl  
  int Result = 0;  
  for (int i = sizeof(Data)-1; i >= 0; i--)  
  {  
    Result |= Data[i];  
    Result <<= (i * sizeof(unsigned char) * 8);  
  }  
  return Result;  
#pragma option pop  
  }  
      
  ......  
      
};

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved