【问题标题】:Where does exception message comes from?异常消息来自哪里?
【发布时间】:2019-07-14 12:14:54
【问题描述】:

当出现 EZeroDivideEOverflowEMathError... 等异常时,它们会显示默认消息。

例如,以下代码引发 EZeroDivide 并带有以下消息:

浮点除以零

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

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

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

默认异常消息从何而来?

【问题讨论】:

  • 消息在 System.SysConst.pas 中定义为资源字符串 SZeroDivide,它是 RTL 源的一部分。
  • 显示的消息在 SysConst.pas 中定义为SZeroDivide,RTL 在引发该异常时使用它。
  • 虽然这个问题很容易回答,但我们想知道您为什么关心这个问题?只是好奇,还是有什么目的?通常,您永远不需要创建和提升自己的 EZeroDivide。你为什么要这样做?
  • 使用system.Error(reZeroDivide) 提出一个。 link, link.
  • @Fabrizio 如果好奇,this question 是松散相关的。

标签: delphi exception delphi-2007


【解决方案1】:

这些异常实例由 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,因此通常需要明确地确定它的范围。

【讨论】:

    猜你喜欢
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多