错误处理
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgErrorHandling
- 最后更新: 2020-06-28
处理运行时错误。
FreeBASIC 可以通过以下方式处理错误:
- 默认情况下,程序对错误不做任何处理——它们被静默忽略,代码继续执行。在这种情况下,代码应在下一行使用
Err函数处理可能的错误。 - 如果使用 -e、-ex 或 -exx 选项编译,FreeBASIC 使用类似 QB 的错误处理。
- 未来的 FreeBASIC OOP 版本可能会实现类似 Java 的 TRY..CATCH...FINALLY 异常处理程序。
注意:以下信息有效,除非错误产生操作系统一般保护错误(例如,如果程序向进程内存区域外写入)。在这种情况下,操作系统将立即停止程序并发出错误提示:FreeBASIC 内部无法阻止这种情况。
默认错误处理
FreeBASIC 的默认行为是设置 ERR 变量并继续执行。
start GeSHi
Dim As Integer e
Open "xzxwz.zwz" For Input As #1
e = Err
Print e
Sleepend GeSHi
(示例程序假设不存在 xzxwz.zwz 文件)。程序不会停止;它设置 ERR 变量并继续执行。可以在下一行处理错误。
某些 IO 函数,如 Open 和 Put #... 可以以函数形式使用,成功时返回错误编号或零。
start GeSHi
Print Open ("xzxwz.zwz" For Input As #1)
Sleepend GeSHi
QuickBASIC 式错误处理
如果在编译时使用了 -e、-ex 或 -exx 开关,程序应启用类似 QB 的错误处理程序。如果没有处理程序处理错误,程序将以错误停止。
注意:如果使用类似 QB 的错误处理,程序员应准备好处理所有错误条件。
start GeSHi
'' Compile with QB (-lang qb) dialect
'$lang: "qb"
On Error Goto FAILED
Open "xzxwz.zwz" For Input As #1
On Error Goto 0
Sleep
End
FAILED:
Dim e As Integer
e = Err
Print e
Sleep
Endend GeSHi
On Error 设置一个错误处理程序,程序发现错误时将跳转到该程序。On Error Goto 0 禁用错误处理。
如果发生错误时未设置错误处理程序,程序将停止并向控制台发送错误消息。
Aborting program due to runtime error 2 (file not found)错误处理程序可以位于程序末尾,就像在 QB 中一样。On Local Error 语句允许在发生错误的同一 Sub 或 Function 末尾设置本地错误处理程序。
start GeSHi
'' Compile with -e
'' The -e command line option is needed to enable error handling.
Declare Sub foo
foo
Sleep
Sub foo
Dim filename As String
Dim errmsg As String
filename = ""
On Local Error Goto fail
Open filename For Input Access Read As #1
Print "No error"
On Local Error Goto 0
Exit Sub
fail:
errmsg = "Error " & Err & _
" in function " & *Erfn & _
" on line " & Erl
Print errmsg
End Subend GeSHi
如果使用了 -e 开关(不管 -lang 方言如何),错误处理程序必须终止程序。
使用(-ex 或 -exx)和 -lang qb 方言时,错误程序可以使用 Resume(重试导致错误的语句)或 Resume Next(继续执行下一条指令)结束。
错误代码
有关运行时错误编号及其含义的列表,请参阅运行时错误代码。
没有定义用户错误代码范围。如果使用 Error 设置错误代码,明智的做法是使用较高的值,以避免与内置错误代码列表发生冲突。(此内置列表以后可能会扩展。)
'On [Local] Error Goto' 语句的使用
'On [Local] Error Goto label' 导致程序在发生错误时立即跳转到指定标签。此类错误可由内置语句(如 'Open'、'Get'、'Put')或使用 Error 语句时触发。
对内置语句的错误检查仅在程序使用 -e、-ex 或 -exx 选项之一编译时才启用。否则不会执行跳转,但命令仍然会消耗处理器时间。
当仅由 Error 语句触发时,'On [Local] Error Goto label' 即使在不使用这些编译选项时也始终有效。
'On Error Goto 0' 停用当前错误处理程序。如果发生错误,FreeBASIC 不会跳转。
可选的 Local 关键字(仅在 Sub/Function 内允许)旨在用于仅在 'On Local Error' 所在的同一过程中定义错误处理程序(例如为了与 PDS 7.1 和 VB Dos 1.0 兼容)。在这种情况下,FreeBASIC 应仅在当前过程中搜索标签。
但目前,编译器忽略 Local 子句,错误处理程序可以在 'On [Local] Error' 所在的同一过程作用域内,也可以在模块的主要部分(如果在过程之前定义)。
使用 -gen gcc 时的例外情况(或对于 fbc 64 位):Local 子句似乎被正确考虑,但在局部作用域内除外!
'On [Local] Error Goto label' 不是在有函数形式语法可用时从内置过程捕获错误的最佳方式。可以直接测试返回错误代码(使用函数返回的错误代码会抑制 QuickBASIC 式错误检查和语句 'On Error Goto')。
建议尝试编写与 -lang fb 方言和 -exx 选项兼容的程序,因为使用 -exx 选项测试程序以进行调试非常有帮助:
避免使用语句
Resume或Resume Next,因为 -lang fb 完全不支持它(编译错误)。另一方面,有时有用时(当没有函数形式可用时),使用语句 'On [Local] Error Goto',因为它可以在 -e、-ex、-exx 中的任何选项下运行。否则(没有错误检查选项),'On [Local] Error Goto' 不活跃(没有编译错误),但它消耗 CPU 时间。
因此,如有必要,通常根据 __FB_ERR__ 的值用条件汇编指令编写 QuickBasic 式错误处理('On [Local] Error Goto label' ..... 'label:' .....),以避免降低执行速度(如果不使用错误检查选项)。
'On Error Goto' 语句(-lang fb)关于编译选项(无、-e/-ex/-exx)的行为通过以下包含多个示例(4 个)的程序进行阐明,该程序可以有或没有错误检查选项编译(4*2=8 个测试):
start GeSHi
#DEFINE Config 1
'#DEFINE Config 2
'#DEFINE Config 3
'#DEFINE Config 4
#IF Config = 1 '-----------------------------------------------------------
Open "does_not_exist" For Input As #1
Print "main end"
Sleep
System
' - with compiler option 'none' :
' console output :
' 'main end'
'
' - with compiler option '-e' or '-ex' or '-exx' :
' console output :
' 'Aborting due to runtime error 2 (file not found) at line 10 of .....'
#ENDIF '-------------------------------------------------------------------
#IF Config = 2 '-----------------------------------------------------------
Dim As Integer Result = Open("does_not_exist" For Input As #1)
If Result <> 0 Then
Print "error code returned: " & Result
Print "file not found (processed by 'Result = Open(.....)')"
End If
Print "main end"
Sleep
End
' - with compiler option 'none' or '-e' or '-ex' or '-exx' :
' console output :
' 'error code returned: 2'
' 'file not found (processed by 'Result = Open(.....)')'
' 'main end'
#ENDIF '-------------------------------------------------------------------
#IF Config = 3 '-----------------------------------------------------------
On Error Goto Error_Handler
Open "does_not_exist" For Input As #1
Print "main end"
Sleep
End
error_handler:
Print "file not found (processed by 'On Error Goto')"
On Error Goto 0
Print "QB-like error handling end"
Sleep
End
' - with compiler option 'none' :
' console output :
' 'main end'
'
' - with compiler option '-e' or '-ex' or '-exx' :
' console output :
' 'file not found (processed by 'On Error Goto')'
' 'QB-like error handling end'
#ENDIF '-------------------------------------------------------------------
#IF Config = 4 '-----------------------------------------------------------
On Error Goto error_handler
Dim As Integer Result = Open("does_not_exist" For Input As #1)
If Result <> 0 Then
Print "error code returned: " & Result
Print "file not found (processed by 'Result = Open(.....)')"
End If
Print "main end"
Sleep
End
error_handler:
Print "file not found (processed by 'On Error Goto')"
On Error Goto 0
Print "QB-like error handling end"
Sleep
End
' - with compiler option 'none' or '-e' or '-ex' or '-exx' :
' console output :
' 'error code returned: 2'
' 'file not found (processed by 'Result = Open(.....)')'
' 'main end'
#ENDIF '-------------------------------------------------------------------end GeSHi
Config=2 和 Config=4 部分表明,当使用显式返回错误代码的函数形式调用 FB 函数时(-lang fb 方言),无论错误检查级别如何('none'、'-e'、'-ex'、'-exx'),'On Error Goto' 都会被绕过。
另请参阅
返回 目录