异常消息来自哪里?

Fab*_*zio 7 delphi exception delphi-2007

当一个像例外EZeroDivide,EOverflow,EMathError...复活,他们似乎有一个默认的消息.

例如,以下代码EZeroDivide使用以下消息引发:

浮点除以零

procedure TForm1.Button1Click(Sender: TObject);
var
  N : Extended;
  D : Extended;
begin
  N := 100;
  D := 0;
  Caption := FloatToStr(N/D);
end;
Run Code Online (Sandbox Code Playgroud)

EZeroDivide浮点除以零

当我EZeroDivide通过代码"手动"引发异常时,我必须将Msg参数传递给构造函数,并将其作为EZeroDivide异常引发,该异常具有空字符串消息:

procedure TForm1.Button2Click(Sender: TObject);
begin
  raise EZeroDivide.Create('');
end;
Run Code Online (Sandbox Code Playgroud)

EZeroDivide没有消息

默认异常消息来自哪里?

J..*_*... 12

这些异常实例由RTL在内部生成.问题中的特定字符串可以在resourcestringSysConst.pas部分找到

 SZeroDivide = 'Floating point division by zero';
Run Code Online (Sandbox Code Playgroud)

在内部,RTL使用该Error方法来引发此类异常.完整的运行时错误列表System在以下枚举中的单元中定义:

TRuntimeError = (reNone, reOutOfMemory, reInvalidPtr, reDivByZero,
  reRangeError, reIntOverflow, reInvalidOp, reZeroDivide, reOverflow,
  reUnderflow, reInvalidCast, reAccessViolation, rePrivInstruction,
  reControlBreak, reStackOverflow,
  { reVar* used in Variants.pas }
  reVarTypeCast, reVarInvalidOp,
  reVarDispatch, reVarArrayCreate, reVarNotArray, reVarArrayBounds,
  reAssertionFailed,
  reExternalException, { not used here; in SysUtils }
  reIntfCastError, reSafeCallError,
  reMonitorNotLocked, reNoMonitorSupport
{$IF defined(LINUX) or defined(MACOS) or defined(ANDROID)}
  , reQuit
{$ENDIF LINUX or MACOS or ANDROID}
{$IFDEF POSIX}
  , reCodesetConversion
{$ENDIF POSIX}
  , rePlatformNotImplemented, reObjectDisposed
  );
Run Code Online (Sandbox Code Playgroud)

如果您有真正的理由自己提出运行时错误,可以通过调用来完成,例如:

 System.Error(reZeroDivide);
Run Code Online (Sandbox Code Playgroud)

如果你非常敏锐,你会注意到单位中Error没有前瞻性声明,System但只存在于实施部分.通常,这会阻止您在其包含单元之外调用方法的可见性,但该System单元在许多方面都是特殊的,并且此方法可在全局访问.请注意,您通常也会包含该Windows单元,并且这将声明一个ERROR通常隐藏的const命名System.Error,因此通常需要明确定义它.