DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: shadowlinux001
今日帖子: 3
在线用户: 4
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 hardnut (麦轲数据管家) ★☆☆☆☆ -
普通会员
2019/11/14 9:10:21
标题:
Delphi 10.3.2疑似Bug 浏览:816
加入我的收藏
楼主:   TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FTestStr:string;
  public
    procedure ShowStr(const AStr:string);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ShowStr(const AStr: string);
begin
  FTestStr := '';
  FTestStr := AStr;
  ShowMessage(FTestStr);
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  tmp:string;
begin
  FTestStr := 'this is a test string';
  ShowStr( FTestStr );  //error

//  ShowStr( System.UniqueString( FTestStr ) );  //编译错误

  tmp := FTestStr;
  ShowStr(tmp); //OK
end;

end.

请有时间的网友再验证下,是不是我的机器的问题.最后老是碰上怪问题,
估计是处理const参数时出了问题
----------------------------------------------
麦轲数据管家--您最贴心的个人数据/知识管理工具
作者:
男 xlonger (xlonger) ▲▲▲▲▲ -
普通会员
2019/11/14 9:47:12
1楼: Berlin 报错
----------------------------------------------
我打的是酱油,而不是别的什么油。
我灌的是口水,而不是别的什么水。
我聊的折腾不是那个不折腾的折腾。
我说的阿娇不是那个邓玉娇的阿娇。
3个代表,6个为什么,9个肠胃炎。
D性强的领导干部都不喜欢热比娅。
我特别要讲的是,屁民网黄色论坛是我经常上网必选的 网站之一
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2019/11/14 10:08:29
2楼: FTestStr := ''; 很有意思。
----------------------------------------------
-
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2019/11/14 10:11:33
2楼: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/System_UniqueString@AnsiString.html
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。
又不靠它 delphi 吃饭,怕甚?
作者:
男 nickemma (N.E) ▲▲▲▲△ -
注册会员
2019/11/14 10:37:31
3楼: @hardnut

你确定代码没有问题吗?我觉得你代码有问题,所以编译器反馈出错。

FTestStr <--定义为Form1的私有变量

FTestStr := 'this is a test string'; <--赋值
ShowStr( FTestStr ); <--出错

我们可以看看ShowStr过程:
procedure TForm1.ShowStr(const AStr: string); <--const不允许修改变量值
begin
  FTestStr := '';    <--有下面语句,这里的置空是多余的
  FTestStr := AStr;  
  ShowMessage(FTestStr);
end;

明白了吗?
ShowStr( FTestStr ),FTestStr在ShowStr过程里用了const定义为不许修改,但是你的过程里面修改了(FTestStr := '')。

我觉得你这个例子乱七八糟,有什么意义???
----------------------------------------------
-
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2019/11/14 11:09:26
4楼: 这样写法,把Delphi的编译器给弄晕了
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲△△ -
注册会员
2019/11/14 13:25:48
5楼: unit Unit1;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FTestStr: string;
  public
    procedure ShowStr(const AStr: string);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  tmp: string;
begin
  FTestStr := 'this is a test string';
  ShowStr(FTestStr); // NO MORE ERROR!!!

  // ShowStr( System.UniqueString( FTestStr ) );  // only const here

  tmp := FTestStr;          // <--- its not necessary!
  ShowStr(tmp); // OK       // <--- its not necessary!
end;

procedure TForm1.ShowStr(const AStr: string);
begin
  // FTestStr := '';  // <---- just delete this line, and your code works!
  FTestStr := AStr;
  ShowMessage(FTestStr);
end;

end.



按此在新窗口浏览图片
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!
作者:
男 vkow (vkow) ▲▲▲▲▲ -
普通会员
2019/11/14 14:34:14
6楼: 你这循环赋值属于找茬。
----------------------------------------------
-
作者:
男 hardnut (麦轲数据管家) ★☆☆☆☆ -
普通会员
2019/11/14 14:47:32
7楼: 我发的这个当然是简化后的代码,是死了N多脑细胞之后发现的真正问题所在. 没有人会这么写,但作为一个编译器, 也不能阻止别人这么写啊.
----------------------------------------------
麦轲数据管家--您最贴心的个人数据/知识管理工具
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/11/14 15:32:20
8楼: 所以,你要吸取教训。提BUG之前要保证自己是个完美的人,否则没资格提,
至于,是不是BUG,已经不重要了,重要的是你不好,哈哈。。。。
----------------------------------------------
-
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2019/11/14 15:37:31
8楼: 1、算法上是允许的,但实际上编译器在FTestStr := ''时已经将内存释放了。
2、如果FTestStr换整数或浮点数,算法是成立的。
3、编译器对的字符串管理的问题。作为算法,函数的常量参数入口时,要复制一份字符串,但实际上字符串是个对象,简单说,Delphi的字符串是对象,赋空时,已经将内存放了,const也没用。
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/11/14 15:50:01
8楼: 你可以提交bug,然而我觉得你既然要改参数的值,那就去掉const,一了百了。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/11/14 16:43:40
9楼: procedure TForm1.Button1Click(Sender: TObject);
var
  tmp:string;
begin
  FTestStr := 'this is a test string';
  ShowStr( FTestStr );  //error

  tmp := FTestStr;
  ShowStr(tmp); //OK
end;

编译没错,运行错误, 内存被你改了。



UniqueString 编译错误是 因为 类型错误,返回值错误。
请你们自己去看函数定义。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/11/14 16:51:04
10楼: procedure TForm1.Button1Click(Sender: TObject);
var
  tmp:string;
begin
  FTestStr := 'this is a test string';
  System.UniqueString( FTestStr );
  ShowStr( FTestStr  );

  tmp := FTestStr;
  ShowStr(tmp); //OK
end;

编译正确,运行错误,理由 一样, 都是内存被你改了。


所以 BUG 到底在 哪里?
----------------------------------------------
(C)(P)Flying Wang
作者:
男 hardnut (麦轲数据管家) ★☆☆☆☆ -
普通会员
2019/11/14 17:11:46
11楼: 我估计是 ShowStr(const AStr: string), FTestStr 作为实参时,没有增加引用记数.

结果 FTestStr  := ''会导内容被释放, 结果 FTestStr := AStr;  执行时, AStr指向的内存已经非法

懂汇编 的朋友可以看看
----------------------------------------------
麦轲数据管家--您最贴心的个人数据/知识管理工具
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2019/11/14 17:42:38
12楼: 就是释放了(call @UStrClr),然后还用的问题

Unit7.pas.75: begin
009EBBE4 53          push ebx
009EBBE5 56          push esi
009EBBE6 8BF2          mov esi,edx
009EBBE8 8BD8          mov ebx,eax
Unit7.pas.76: FTestStr := '';
009EBBEA 8D83F0030000     lea eax,[ebx+$000003f0]
009EBBF0 E8AFE3A1FF       call @UStrClr
Unit7.pas.77: FTestStr := AStr;
009EBBF5 8D83F0030000     lea eax,[ebx+$000003f0]
009EBBFB 8BD6          mov edx,esi
009EBBFD E882E7A1FF       call @UStrAsg
Unit7.pas.78: ShowMessage(FTestStr);
009EBC02 8B83F0030000     mov eax,[ebx+$000003f0]
009EBC08 83C9FF          or ecx,-$01
009EBC0B 83CAFF          or edx,-$01
009EBC0E E8E575BCFF       call ShowMessagePos
Unit7.pas.79: end;
009EBC13 5E          pop esi
009EBC14 5B          pop ebx
009EBC15 C3          ret
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/11/14 20:04:26
13楼: 其实就是const作为语法糖有副作用,所以使用时需要遵循一定的规则,建议楼主百度一下“Delphi const”,应该可以找到大量相关文章。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 dawnhawk (dawnhawk) ★☆☆☆☆ -
盒子活跃会员
2019/11/15 11:29:38
14楼: 前几天在坛子里下载了《Delphi High Performance》
在102页作者说:
const 前缀有点不同。当它被使用时,编译器将阻止我们对参数进行任何更 改。(我们很快就会看到,也有一些例外。)实际上,const 是在我们想要传递大量 数据(例如,一条记录)时使用的优化前缀。它将确保参数通过引用传递,而编译 器将确保数据没有更改。 当参数是托管类型(例如字符串或接口)时,const 前缀也很有用。当按值传递 此类类型时,代码将在方法开始时递增引用计数,在结束时递减引用计数。如果 参数被标记为 const,则引用计数不会增加/减少,这在长期内会产生影响。


所以,在调用ShowStr时,并没有增加引用计数。FTestStr被修改后AStr指向了无效地址。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/11/15 13:09:19
15楼: 为啥你们都讨论 运行后出错的问题,这不是明摆着的吗?
不出错 才是 BUG。

楼主说的是 编译错误啊。

基础中的基础啊。楼主 应该 明白,BUG 是他自己。不是 IDE。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 hardnut (麦轲数据管家) ★☆☆☆☆ -
普通会员
2019/11/15 17:09:50
16楼: 提了个issue:
https://quality.embarcadero.com/browse/RSP-26629
----------------------------------------------
麦轲数据管家--您最贴心的个人数据/知识管理工具
作者:
男 crystalmoon (crystalmoon) ★☆☆☆☆ -
盒子活跃会员
2019/11/18 17:21:11
17楼: 附和 dawnhawk 的 意见,
showstr里,把FTestStr自己传了进去, 
而const 类似 只读模式的var,传的其实是个地址。然后附空值,根据copy on write,FTestStr指向了新地址,那么传入的原来的地址已经非法,所以下面再FTestStr := AStr;的时候,就引用到了非法地址报错。

下面的一个编译错误,我的理解是,const 类似var 你必须先把 UiqueString(xxx)复制后的东西传递个一个变量,然后再传入,不能自己直接把函数结果传入。

综合上面的论点,我认为,这应该不是bug.
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲▲ -
普通会员
2019/11/18 18:14:20
18楼: 楼主啊,大家都告诉你不是 BUG,你怎么就 听不进去?
----------------------------------------------
(C)(P)Flying Wang
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行39.0625毫秒 RSS