CnPack Forum » 技术板块灌水区 » CnPack Delphi Bug 集


2007-3-17 11:25 skyjacker
CnPack Delphi Bug 集

CnPack Delphi Bug 集

整理: SkyJacker
http://www.cnpack.org
CnPack IV  QQ Group: 130970
Bug发布人: 谁知我心


2007-3-16 谁知我心发布以下 D6 Bug
Bug1:
unit Masks;
function Matches(P: PChar; Start: Integer): Boolean;

中的
msMBCSLiteral:
while (P^ <> #0) do
begin
  if (P^ <> LeadByte) then Inc(P, 2)
  else
  begin
   Inc(P);
   if (P^ = TrailByte) then
     Break;-->bug
   Inc(P);
  end;
end;

解决:
if (P^ = TrailByte) then
begin
dec(P);
Break;-->bug就解决了中文匹配的问题
end;

Bug2:
d6还有一个bug就是ado 的int64的问题。本来是负数变成正数,也已经解决了

你改了这些编译后的VCL版本和原来的不一样,那如果编译成DCU和别人的程序要交互会很麻烦吧。

2007-3-17 11:34 skyjacker
Bug3: 2007- 03-17  SkyJacker 发布 Delphi 默认意外处理函数可能发生意外.
测试环境: D6 +up2
procedure TApplication.ShowException(E: Exception);
var
  Msg: string;
begin
  Msg := E.Message;
  if (Msg <> '') and (AnsiLastChar(Msg) > '.') then Msg := Msg + '.';
  // 在消息的末尾加个 '.' ,但是太不严格了吧。因为在 '.' 的前面还有其他常见的 ascii 字符。
  // 这一句到底要实现什么功能呢?谁能告诉我。
  // 直接将这一句注释掉,应该更好。或者干脆写 msg = '未知 E.Message';
  // 为什么注释掉更好,继续往下看就会更明白了。
  MessageBox(PChar(Msg), PChar(GetTitle), MB_OK + MB_ICONSTOP);
end;

AnsiLastChar 返回的是指向字符串最后一个字符的指针。
那么 (AnsiLastChar(Msg) > '.')  可以这样写吗?一个指针和一个字符的比较。
测试发现: 如果 一个 PChar 与 一个字符比较, Delphi 会自动将 PChar 转为 PChar^。
有意思吧。

再来 AnsiLastChar 源码
function AnsiLastChar(const S: string): PChar;
var
  LastByte: Integer;
begin
  LastByte := Length(S);
  if LastByte <> 0 then
  begin
    while ByteType(S, LastByte) = mbTrailByte do Dec(LastByte);
    Result := @S[LastByte];
  end
  else
    Result := nil; // 如果 S = '' ,则返回 nil
end;

注意了,如果使用 AnsiLastChar 要注意空指针的问题:
比如:
  Msg := '';
  if (AnsiLastChar(Msg) >= '.') then
将会出现访问非法内存 $00000000 的错误。  

再返回来看
  Msg := E.Message;
  if (Msg <> '') and (AnsiLastChar(Msg) > '.') then Msg := Msg + '.';

也就是说, Delphi 并不能保证 E.Message 不为空。因此,加了 (Msg <> '') 的条件。
问题又来了,既然不能保证 E.Message 不为空,又因为 if A and B 这种条件会因为编译条件的不同而产生不同的结果。
因此,将编译选项改为完全计算,在Compiler Options 对话框中选择Complete Boolean Evaluation 选项,
那么,"Read of Address 00000000" 应该是意外处理中的意外了。

之所以认为是 Bug, 是因为 Delphi 并没有说明它所有的编译必须使用部分编译.
还有实在不能理解 if (Msg <> '') and (AnsiLastChar(Msg) > '.') then Msg := Msg + '.'; 的功能.

[[i] 本帖最后由 skyjacker 于 2007-3-17 11:37 编辑 [/i]]

2007-3-17 14:48 Passion
“你改了这些编译后的VCL版本和原来的不一样,那如果编译成DCU和别人的程序要交互会很麻烦吧。”
——这个我倒是不认为会有什么麻烦,一来这几个函数不存在啥交互的,二来是bug,修正总比没修正好。

这个bug修正不同于模块间的数据结构的接口,后者一个改了另外不改就会出问题。

2007-3-17 15:49 kendling
哈,VCL的代码,,

2007-3-19 09:35 zzzl
期待bds2006的bug

2007-3-19 12:02 zjy
[quote]原帖由 [i]skyjacker[/i] 于 2007-3-17 11:34 发表
Bug3: 2007- 03-17  SkyJacker 发布 Delphi 默认意外处理函数可能发生意外.
测试环境: D6 +up2
procedure TApplication.ShowException(E: Exception);
var
  Msg: string;
begin
  Msg := E.Message;
  if (Msg < ... [/quote]
if (Msg <> '') and (AnsiLastChar(Msg) > '.') then Msg := Msg + '.';
这行代码的作用是:如果错误消息没有用 . , ! 这些标点符号结尾,自动在后面加上一个英文的句号。
不过这样一来我们会发现一个很不爽的问题:我们有时会在异常消息中用中文的句号"。"结束,结果你会发现弹出来的异常框中中文句号后面会多个英文的句号:(

2007-3-19 14:17 skyjacker
有意思.

不加点的消息会有如下 :
1、  . , ! 正好在 . 的前面的符号
2、意外(...)  括号内
3、"意外"  
.....

Borland  程序员也有偷懒的时候:lol:

2007-3-20 10:10 kendling
哈哈哈,我也偷懒。。。。而且经常。。。

2007-3-20 10:54 jAmEs_
回复 #6 zjy 的帖子

还真是这样。。。

页: [1]
查看完整版本: CnPack Delphi Bug 集


Powered by Discuz! Archiver 5.0.0  © 2001-2006 Comsenz Inc.