我有一个应用程序,在调用FormatDateTime
时偶尔会返回整数溢出。虽然我发现了问题here和here,但我不知道是什么情况触发了这个问题。
我目前的解决方法是包装函数并处理异常:
function FormatDateTimeEx (const FormatString : ANSIString ;
DateTime : TDateTime) : ANSIString ;
begin
try
Result := FormatDateTime (FormatString, DateTime) ;
except
Result := '???' ;
end ;
end ;
解决了导致编译后的可执行文件崩溃的问题,但是如果调试器在IDE中运行程序时没有在EIntOverflow
异常中中断,我也会更喜欢它。我不想通过告诉IDE忽略EIntOverflow
异常来做到这一点,因为当发生未捕获的整数溢出时,它不会在其他情况下中断(对吗?)。
是否有一种编程方式(编译时或运行时)告诉IDE本地忽略异常类,对于那些可能发生异常的情况,你已经知道并正在处理它?</ p >
答案 0 :(得分:3)
是否有一种编程方式(编译时或运行时)告诉IDE本地忽略异常类,对于那些可能发生异常的情况,你已经知道并正在处理它?</ p >
没有。
您无法要求调试器忽略某些EIntOverflow
例外但不会忽略其他例外情况。你可以忽略它们,也可以不忽略它们。您可以通过异常类控制调试器中哪些异常中断的唯一方法。您不能要求调试器忽略程序的某个部分中的异常,而忽略另一部分中的异常。
坦率地说,在我看来,解决这个问题的正确方法是弄清楚为什么你首先会触发这些例外。并采取措施防止它们发生。例外是您需要解决的代码中的错误的症状。
答案 1 :(得分:3)
您无法控制调试器异常处理,但您可以控制导致其中一些异常的编译器选项。 以下是如何在本地禁用编译器切换然后返回到先前状态:
1)初始化 - 在单元的开头某处或者可能在单独的* .inc文件中。
{$IFOPT R+}
{$DEFINE RangeCheckOn}
{$ENDIF}
这里保存编译器开关的初始状态(即在项目设置中设置)状态。 2)现在,用法:
{$R-}
...your code here with disabled switch...
{$IFDEF RangeCheckOn}
{$R+}
{$ENDIF}
这里禁用开关,在没有它的情况下执行一些代码,并在完成后将其恢复到初始状态。
我正在使用这个技巧在(U)Int64上进行一些位移操作,这会在触摸MSB时产生错误的EIntOverflow异常(编译器错误是XE2的实际错误,对于新版本不确定)。
但我同意以前的答案,你应该检查引发异常的真正原因。我建议你使用FormatEx版本,如果出现异常,将记录参数值。因此,您可以跟踪导致异常的值,并检查它是否是可重现的案例。
答案 2 :(得分:1)
是否有一种编程方式(编译时或运行时)告诉IDE本地忽略异常类,对于那些可能发生异常的情况,你已经知道并正在处理它?</ p >
不在代码中,没有。但是,可以使用断点在调试器中完成。
用两个断点包装受影响的代码:
function FormatDateTimeEx(const FormatString: AnsiString; DateTime: TDateTime): AnsiString;
begin // <-- breakpoint
try
Result := FormatDateTime (FormatString, DateTime) ;
except
Result := '???';
end;
end; // <-- breakpoint
进入第一个断点的属性并启用忽略后续例外选项并禁用中断选项。
进入第二个断点的属性并启用处理后续例外选项并禁用中断选项。