发现C++Builder 2010一组类BUG

发现C++Builder 2010一组类BUG

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

    今天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程序猿警觉。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116748.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • csgo电脑人怎么控制(csgo守护模式)

    网吧以浓厚的电竞氛围,吸引了很多游戏玩家前去消费。但常去网吧的人会发现:玩穿越火线、英雄联盟、绝地求生甚至守望先锋的人都不在少数,却单单少了CSGO玩家的身影,这是为什么?随着前两年绝地求生的“吃鸡”热潮来袭,网吧早已升级了电脑配置,绝大多数游戏玩家都可流畅地进行自己喜欢的游戏,难道CSGO玩家如何不合群?让我们来熟悉一下进入网吧后的一系列操作就可以得到结论了!去网吧:穿越火线/英雄联盟/绝地求生…

    2022年4月12日
    220
  • cshtml的美化

    cshtml的美化c#webapp美化工作美化工作更改css框架css在cshtml中的位置网上的bootstrap模板资源1.从网站上下载模板2.使用模板更多的资料美化工作默认大家已经掌握了MVC框架的概念和使用方式,本文章只将如何在MVC基础上进行简单的美化工作更改css框架css在cshtml中的位置对html语言有所了解的各位应该知道,css一般写在头中,也就是<head></head>所在的位置中,在cshtml中也是这样。注意看MVC框架的_Layout.cshtml中的

    2022年6月16日
    33
  • jQuery网页版五子棋小游戏源码下载

    体验效果:http://hovertree.com/texiao/game/4/网页五子棋源代码:jquery五子棋游戏-黑子白子先手后手开始胜率:100%更多:http://www.cnblogs

    2021年12月21日
    38
  • MyBatis面试题(2020最新版)

    MyBatis面试题(2020最新版)整理好的MyBatis面试题库,史上最全的MyBatis面试题,MyBatis面试宝典,特此分享给大家MyBatis介绍MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO(Plai…

    2022年6月14日
    28
  • Sublime Text 3 全程详细图文使用教程

    Sublime Text 3 全程详细图文使用教程转自:http://www.cnblogs.com/wind128/p/4409422.html一、&nbsp;前言&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用SublimeText也有几个年头了,版本也从2升级到3了,但犹如寒天饮冰水,冷暖尽自知。最初也是不知道从何下手,满世界…

    2022年5月31日
    33
  • 北京儿研所电话预约挂号流程详解

    北京儿研所电话预约挂号流程详解北京儿童医院电话预约挂号流程详解  北京儿童医院以其权威的学科地位、优秀的医师团队及先进的技术设备吸引来自全国各地的患儿前来就诊,与此同时,挂号难就成了患儿家长及院方最头疼也最无奈的问题,门诊楼扩建的

    2022年8月6日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号