今天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
} ...... };

上面測试用的集合类TTests最小成员值=0,最大成员值=16,按源代码数据长度定义公式计算得3。Byte类型的数组Data长度=4,測试代码中的集合类变量t1和t2的数据分别为"\0\x80\0\0"和"\0\0\1\0",在ToInt函数转换时,t1的有效起始下标i=1,Result赋值0x80后共左移了2次8位,结果为0x8000(32768);而t2的有效起始下标i=2,Result赋值1后左移了3次共24位(即2 * 1 * 8 = 16,1 * 1 * 8 = 8,0 * 1 * 8 = 0),结果为0x1000000(16777216)。

能够将源代码中ToInt函数做例如以下改动:

    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];
if (i)
Result <<= (sizeof(unsigned char) * 8);
}
return Result;
#pragma option pop
}

我只是看C++Builder 2010,它仅涉及ToInt功能,其它版本号或功能不明确是否该问题。显然,这BUG有可能是致命的程序。希望你C++Builder程序猿警觉。

发现C++Builder 2010一组类BUG的更多相关文章

  1. c++ builder 2010 错误 F1004 Internal compiler error at 0x9740d99 with base 0x9

    今天遇到一个奇怪的问题,拷贝项目后,在修改,会出现F1004 Internal compiler error at 0x9740d99 with base 0x9 ,不管怎么改,删除改动,都没用,关闭 ...

  2. Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析

    前言 前些天,测试MM发现了一个比较奇怪的bug. 具体表现是: 1.将app包通过电脑QQ传送到手机QQ上面,点击安装,安装后选择打开app (此间的应用逻辑应该是要触发 [闪屏页Activity] ...

  3. 【转载】Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析

    前言 前些天,测试MM发现了一个比较奇怪的bug. 具体表现是: 1.将app包通过电脑QQ传送到手机QQ上面,点击安装,安装后选择打开app (此间的应用逻辑应该是要触发 [闪屏页Activity] ...

  4. 使用iskindofclass来发现对象是否是某类或其子类的实例

    发现对象是否是特定类或其子类的实例 要发现对象是否是某类或其子类的实例,请在对象上调用 isKindOfClass: 方法.当应用程序需要发现其响应的消息(实现的或继承的),它有时进行以上的检查. s ...

  5. c++builder 读写文件类

    c++builder 读写文件类 TStreamReader.TStreamWriter读取一行 http://docwiki.embarcadero.com/CodeExamples/XE8/en/ ...

  6. 0422 发现( 数学口袋精灵)bug

    团队博客地址: 甘佳萍:http://www.cnblogs.com/gjpg/ 李鹏飞:http://www.cnblogs.com/l549023320/ 赵创佳:http://www.cnblo ...

  7. 发现一个c++ vector sort的bug

    在开发中遇到一个非常诡异的问题:我用vector存储了一组数据,然后调用sort方法,利用自定义的排序函数进行排序,但是一直都会段错误,在排序函数中打印参加排序的值,发现有空值,而且每次都跟同一个数据 ...

  8. 发现了一个entity framework的BUG

    小弟学浅才疏可能是小题大做,但遇上了并且让我麻烦了一阵,就值得记下来 BUG的过程就是我在建立实体模型的时候 命名了一个叫system的实体模型 导致了所有生成类中 引用using system失败

  9. 发现javax.xml.parsers.SAXParser有bug

    javax.xml.parsers.SAXParser有bug, 我发现的地方在characters(char[] ch, int start, int length) length偶尔会变小,导致截 ...

随机推荐

  1. Swift - 使用网格(UICollectionView)进行流布局

    一.网格UICollectionView最典型的例子是iBooks.其主要属性如下: 1,layout 该属性表示布局方式,有Flow.Custom两种布局方式.默认是Flow流式布局. 2,Acce ...

  2. [Android学习笔记]使用getIdentifier()获取资源Id

    使用getIdentifier()获取资源Id Android中可以使用getIdentifier()获取资源ID ex: 根据图片名称获取图片Id private int getImageResId ...

  3. 4.2、Libgdx每个模块概述

    (原版的:http://www.libgdx.cn/topic/34/4-2-libgdx%E5%90%84%E4%B8%AA%E6%A8%A1%E5%9D%97%E6%A6%82%E8%A7%88) ...

  4. FMCG行业是什么行业?

    FMCG行业是什么行业?_百度知道 FMCG行业是什么行业?    2008-05-21 20:03 搏浪峰 | 分类:创业投资 | 浏览13089次 在网上看到搜狐公司招聘“FMCG行业(高级)客户 ...

  5. RFC2889转发性能測试用例设计和自己主动化脚本实现

    一.203_TC_FrameRate-1.tcl set chassisAddr 10.132.238.190 set islot 1 set portList {9 10} ;#端口的排列顺序是po ...

  6. WebService的相关使用

    近期公司项目使用WebService ,这里简单做个总结. 事实上详细使用细节有些情况下须要改,还须要看实际情况,须要与server联调,详细沟通. 比方公司连接,非要把envelope.dotNet ...

  7. Liftoff Software | Next stop, innovation

    Liftoff Software | Next stop, innovation Previous Next Gate One 1.1 Now Available Submitted by Dan M ...

  8. ubuntu配置jdk脚本以及导致开不了机的解决方案

    关于在那个文件里配置jdk脚本,有些大牛总结了四个地方,大体就是ubuntu系统启动后会默认加载的四个地方.例如:/etcenvironment,/etc/profile这两个文件处于系统层面的,还有 ...

  9. C++操作符operator的另一种用法

    http://blog.csdn.net/memewry/article/details/7833314 参考地址 今天在程序员面试宝典上看到这样一道题目:  A C++ developer want ...

  10. poj3613(恰经过N条边的最短路)

    题目连接:http://poj.org/problem?id=3613 题意:从S 到 T 经过边得个数恰为k的最短路是多少. 分析:01邻接矩阵A的K次方C=A^K,C[i][j]表示i点到j点正好 ...