异常消息从何而来?

时间:2019-02-20 17:57:25

标签: delphi exception delphi-2007

引发EZeroDivideEOverflowEMathError ...之类的异常时,它们会显示一条默认消息。

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

  

浮点除以零

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

EZeroDivide Floating point division by zero

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

procedure TForm1.Button2Click(Sender: TObject);
begin
  raise EZeroDivide.Create('');
end;

EZeroDivide without message

默认异常消息来自哪里?

1 个答案:

答案 0 :(得分:12)

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

 SZeroDivide = 'Floating point division by zero';

内部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
  );

如果您有真正的理由引发运行时错误,则可以通过调用来做到这一点,例如:

 System.Error(reZeroDivide);

如果您非常观察,您会注意到ErrorSystem单元中没有前向声明,而仅在实现部分中存在。通常,这将使您无法在其包含单位之外调用该方法,但是System单位在许多方面都很特殊,并且可以全局访问此方法。请注意,您还将经常包含Windows单元,并且这会声明一个名为ERROR的常量,该常量通常会隐藏System.Error,因此通常需要对其进行显式作用域。