关于Abort的一点疑问 |
尚未結案
|
fangwy
中階會員 發表:99 回覆:139 積分:62 註冊:2003-09-10 發送簡訊給我 |
我在写代码时喜欢这样处理
function a():Boolean;
var
i: string;
j: integer;
dbRet:Boolean;
begin
try
给i赋值;
j := StrToInt(i);
if j > 9 then
Abort;
a的其他处理
dbRet := True;
except
dbRet := False;
end;
//返回前的一些必要处理
a := dbRet;
end; function b():Boolean;
var
dbRet:Boolean;
begin
try
dbRet := False;
if not a() then //这里a()虽然处理失败,但我仅仅是不想做后面的处理,但仍返回成功
begin
dbRet := True; <----
Abort;
end;
b其他处理;
dbRet := True;
except
end;
//返回前的一些必要处理
b := dbRet;
end; function c():Boolean;
var
dbRet:Boolean;
begin
try
if not b() then
begin
Abort;
end;
c其他处理1;
c其他处理2;
c其他处理3;
dbRet := True;
except
dbRet := False;
end;
//返回前的一些必要处理
c := dbRet;
end;
这样做主要是因为我觉得处理流程清晰,不会造成很多if的嵌套,又能够处理一些异常如a()中的j := StrToInt(i)可能出现无效的数值,
还可将函数的结束处理集中到函数末尾处理.但是今天出了个怪问题:
在c()中,调用b()返回true后(是在a()处理失败的情况下返回的true,箭头指示的位置),并没有去处理'c其他处理1'而是跳到了'c其他处理3'(实际代码中甚至跳到其他分支去了(即本不应处理的else中)).
代码实在太长了无法贴上,上面举个例子,基本与我的代码处理情况一致.
我想问问先知,我这样使用Abort是否有问题;我出现的异常是否与这样的处理方式有关;如果except换成finally是否有一样的问题或有新的问题?
再说明一下,上述问题,后来自已消失了. 發表人 - fangwy 於 2004/10/10 16:28:53
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
hi,fangwy: 1.原則上,abort其實可以看成是raise一個exception,只不過是舉發一個沒有訊息的例外而已. 2.我想,你可能追錯程式碼了.在function c中,如果not b()的話,接著會執行的是abort,那麼,從abort到except之間的程式碼是不會被執行的,而會直接跳到except-end之間的程式碼執行,然後接著再執行function c中,返回前的一些必要处理及最後的c := dbRet; 3.我想,你可能弄錯了一個地方.如果abort有被try-except-end包住,那麼就會執行except以後的指令,如果沒有的話,那麼abort接著就是結束,不會再執行.其實,你可以試著執行以下的程式碼即可知道流程
procedure TForm1.Button1Click(Sender: TObject); begin try ShowMessage('1'); abort; showMessage('2'); except ShowMessage('error'); end; ShowMessage('continue'); end;在上例中,showMessage('2')是不會被執行到的 發表人 - change.jian 於 2004/10/10 20:12:09 |
fangwy
中階會員 發表:99 回覆:139 積分:62 註冊:2003-09-10 發送簡訊給我 |
谢谢change.jian,不过你可以没理解我的说明:
if not b() then
begin
Abort;
end;
b()返回的是true,理应执行'c其他处理1;',但实际却跳到其他语句去了,完全不符合流程
其实这种问题我有遇过类似的,当时我是声明了一个string变量,然后用CopyMemory将一个Buffer的数据复制过来,如下:
aaa:string
bbb:buffer: array[100]of Char;
CopyMemory(PChar(aaa),@buffer,100);
结果出现某些语句总是执行不到,
后来将aaa:string改成aaa:string[101];就没问题了.
但这一次没有发现类似问题,不知为何出现类似现象.
这样的问题可能没有出问题的程序码确实难以分析,我只是想知道我这样使用Abort是否安全,即会不会引起一些意想不到的问题. 發表人 - fangwy 於 2004/10/11 09:28:11
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
我猜你的情況應該如下: 如果你的CopyMemory(PChar(aaa),@buffer,100);這行指令是在FUNCTION B,而且沒有被try-except-end包住.那麼當CopyMemory這行指令出錯時,在function C這裡呼叫function B的這行指令就會舉發例外,這個結果會跟你的function B回傳False是一樣的情形,因為回傳False之後,接著執行abort,那當然後面的指令就不會執行了到. 我想,你的問題應該是出現在你的function最後的"返回前的處理"這裡.因為這裡沒有被try-except-end包起來,一但有出錯,那麼呼叫這個function的程式碼就會有例外被舉發.而雖然你呼叫function時,會用try-except-end包住,但因為如果回傳不是True時,你的程式也會舉發例外,所以這時會造成混淆. 你可以試著檢查看看,是否都在"返回前的處理"這段程式碼裡有錯,才造成程式的流程不是你預期的結果.
引言: 谢谢change.jian,不过你可以没理解我的说明: if not b() then begin Abort; end; b()返回的是true,理应执行'c其他处理1;',但实际却跳到其他语句去了,完全不符合流程 其实这种问题我有遇过类似的,当时我是声明了一个string变量,然后用CopyMemory将一个Buffer的数据复制过来,如下: aaa:string bbb:buffer: array[100]of Char; CopyMemory(PChar(aaa),@buffer,100); 结果出现某些语句总是执行不到, 后来将aaa:string改成aaa:string[101];就没问题了. 但这一次没有发现类似问题,不知为何出现类似现象. 这样的问题可能没有出问题的程序码确实难以分析,我只是想知道我这样使用Abort是否安全,即会不会引起一些意想不到的问题. 發表人 - fangwy 於 2004/10/11 09:28:11 |
fangwy
中階會員 發表:99 回覆:139 積分:62 註冊:2003-09-10 發送簡訊給我 |
谢谢change.jian的耐心分析,因代码太长了,只好写一些抽象的实例,可能没表达的得清楚:
CopyMemory(PChar(aaa),@buffer,100)不在这一次的代码中,我只是说以前使用CopyMemory(PChar(aaa),@buffer,100)时有出过类似错误,而且也与
try...except...end结构无关,因为当时的情况是莫名其妙的跳过一行代码,例如代码的流程如下(代码1-4分别代表代码中的一行):
代码1;
代码2;
diSeq := 0;
代码3;
代码4;
.
.
.
执行完'代码2'直接跳到了'代码3'执行,把'diSeq := 0'给略了.我设了断点,按F8一步步执行,清楚的看到'diSeq:=0'被跳过了.
再次说明,这里只是描述以前出错的情况,与这一次的情况不同但错误现象类似. 另外'返回前的处理'中我一般做些简单的处理,如给传值型参数赋值以返回相关数据,如果有出错可能的处理,我还是会考虑将其放在try...except...end中. 發表人 - fangwy 於 2004/10/11 14:21:17
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
1.如果diSeq這個變數只在這一行出現,那麼Dephi會不執行是正常的,因為diSeq給不給值對執行結果沒有影響. 2.如果後面還會對diSeq去做處理,那麼我就不曉得為什麼你的程式碼會突然莫名的跳過某一行.老實說,我還沒碰過,如果有,那真是Delphi很大的一個bug了. 3.因為沒有看到你實際的程式碼,實在沒有辦法去找到原因(如果原因真的不簡單的話),看有沒有其他大大有這樣的經驗可以提供了 <>< face="Verdana, Arial, Helvetica">引言:
谢谢change.jian的耐心分析,因代码太长了,只好写一些抽象的实例,可能没表达的得清楚:
CopyMemory(PChar(aaa),@buffer,100)不在这一次的代码中,我只是说以前使用CopyMemory(PChar(aaa),@buffer,100)时有出过类似错误,而且也与
try...except...end结构无关,因为当时的情况是莫名其妙的跳过一行代码,例如代码的流程如下(代码1-4分别代表代码中的一行):
代码1;
代码2;
diSeq := 0;
代码3;
代码4;
.
.
.
执行完'代码2'直接跳到了'代码3'执行,把'diSeq := 0'给略了.我设了断点,按F8一步步执行,清楚的看到'diSeq:=0'被跳过了.
再次说明,这里只是描述以前出错的情况,与这一次的情况不同但错误现象类似. 另外'返回前的处理'中我一般做些简单的处理,如给传值型参数赋值以返回相关数据,如果有出错可能的处理,我还是会考虑将其放在try...except...end中. 發表人 - fangwy 於 2004/10/11 14:21:17
|
fangwy
中階會員 發表:99 回覆:139 積分:62 註冊:2003-09-10 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |