好吧,打擊我!這看起來很錯,我必須自己嘗試,而且你是對的!我已經縮小了這個事實,即這是操作系統本身而不是德爾福產生的操作系統異常(除以零)。如果你嘗試自己提出一個EIntError,你會得到預期的行爲,而不是你上面看到的。請注意,只要您自己引發異常,就會發生預期行爲。
更新:在System.pas單元有一個名爲當異常被重新提出了下面的代碼:
{ Destroy any objects created for non-delphi exceptions }
MOV EAX,[EDX].TRaiseFrame.ExceptionRecord
AND [EAX].TExceptionRecord.ExceptionFlags,NOT cUnwinding
CMP [EAX].TExceptionRecord.ExceptionCode,cDelphiException
JE @@delphiException
MOV EAX,[EDX].TRaiseFrame.ExceptObject
CALL TObject.Free
CALL NotifyReRaise
因此如果異常不是一個Delphi異常(在這種情況下,OS異常),則(修改的)「Delphi」異常被釋放,並且重新引發原始異常,從而丟棄對異常所做的任何更改。案件結案!
更新2:(忍不住自己)。您可以通過以下代碼重現此操作:
type
TThreadNameInfo = record
InfoType: LongWord; // must be $00001000
NamePtr: PAnsiChar; // pointer to message (in user address space)
ThreadId: LongWord; // thread id ($ffffffff indicates caller thread)
Flags: LongWord; // reserved for future use, must be zero
end;
var
lThreadNameInfo: TThreadNameInfo;
with lThreadNameInfo do begin
InfoType := $00001000;
NamePtr := PAnsiChar(AnsiString('Division by zero'));
ThreadId := $ffffffff;
Flags := $00000000;
end;
RaiseException($C0000094, 0, sizeof(lThreadNameInfo) div sizeof(LongWord), @lThreadNameInfo);
玩得開心!
謝謝米莎。我以爲我正在放棄情節! – Paul
除零除非是操作系統異常。這是硬件異常,由CPU本身引發(因此,它是異步異常)。 OS和Delphi異常都是軟件異常,通過特定的代碼調用引發(因此它是同步異常)。因此,問題不在於操作系統和Delphi的異常,而在於Delphi和非Delphi的異常。 「提高;」重新引發原始異常(可能是硬件或軟件異常),所以如果原始異常是Delphi異常,那麼只保留Delphi對象中的任何更改。這很合乎邏輯。 – Alex