C++ Builder 2010集合类的一个BUG2014-11-11今天用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());// 32768ShowMessage(t2.ToInt());// 16777216}
测试代码中的集合类变量t1,t2分别定义为第15位和第16位,显示结果应该分别为32768和65536,t1结果32768是正确的,t2显示却为16777216,显然是错误的。接下来,我用Delphi 2010写了类似的测试代码:
typeTTest = (tt0, tt15 = 15, tt16 = 16);TTests = set of TTest;procedure TForm1.Button1Click(Sender: TObject);vart1, t2: TTests;begint1 := [tt15];t2 := [tt16];ShowMessage(IntToStr(LongWord(t1)));// 32768ShowMessage(IntToStr(LongWord(t2)));// 65536end;
而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-inlint 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}......};
上面测试用的集合类TTests最小成员值=0,最大成员值=16,按源码数据长度定义公式计算得3,Byte类型的数组Data长度=4,测试代码中的集合类变量t1和t2的数据分别为"