Skip to content

错误处理


处理运行时错误。

FreeBASIC 可以通过以下方式处理错误:

  • 默认情况下,程序对错误不做任何处理——它们被静默忽略,代码继续执行。在这种情况下,代码应在下一行使用 Err 函数处理可能的错误。
  • 如果使用 -e-ex-exx 选项编译,FreeBASIC 使用类似 QB 的错误处理。
  • 未来的 FreeBASIC OOP 版本可能会实现类似 Java 的 TRY..CATCH...FINALLY 异常处理程序。

注意:以下信息有效,除非错误产生操作系统一般保护错误(例如,如果程序向进程内存区域外写入)。在这种情况下,操作系统将立即停止程序并发出错误提示:FreeBASIC 内部无法阻止这种情况。

默认错误处理

FreeBASIC 的默认行为是设置 ERR 变量并继续执行。

start GeSHi

vb
Dim As Integer e
Open "xzxwz.zwz" For Input As #1
e = Err
Print e
Sleep

end GeSHi

(示例程序假设不存在 xzxwz.zwz 文件)。程序不会停止;它设置 ERR 变量并继续执行。可以在下一行处理错误。

某些 IO 函数,如 OpenPut #... 可以以函数形式使用,成功时返回错误编号或零。

start GeSHi

vb
Print Open ("xzxwz.zwz" For Input As #1)
Sleep

end GeSHi

QuickBASIC 式错误处理

如果在编译时使用了 -e-ex-exx 开关,程序应启用类似 QB 的错误处理程序。如果没有处理程序处理错误,程序将以错误停止。

注意:如果使用类似 QB 的错误处理,程序员应准备好处理所有错误条件。

start GeSHi

vb
'' 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
End

end GeSHi

On Error 设置一个错误处理程序,程序发现错误时将跳转到该程序。On Error Goto 0 禁用错误处理。

如果发生错误时未设置错误处理程序,程序将停止并向控制台发送错误消息。

Aborting program due to runtime error 2 (file not found)

错误处理程序可以位于程序末尾,就像在 QB 中一样。On Local Error 语句允许在发生错误的同一 SubFunction 末尾设置本地错误处理程序。

start GeSHi

vb
'' 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 Sub

end 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 选项测试程序以进行调试非常有帮助:

  • 避免使用语句 ResumeResume 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

vb
#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' 都会被绕过。

另请参阅

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系