SDL3_API分类参考_断言(CategoryAssert)

2026-3-6 / 0 评论 / 5 阅读

断言子系统(CategoryAssert)

SDL 提供的增强型断言宏,功能远超常规的 assert 宏,核心特性如下:

  • 利用 sizeof 运算符特性:禁用的断言会从编译代码中完全移除,且仅在断言中引用的变量不会触发“未使用变量”的编译器警告;
  • 避免悬空 else 问题:支持 if (x) SDL_assert(y); else do_something(); 这类写法,行为稳定;
  • 跨平台一致性:不依赖各平台编译器/C 运行时的实现,所有平台行为统一;
  • 多级别断言:提供 SDL_assertSDL_assert_releaseSDL_assert_paranoid 等不同级别,而非“全有或全无”的单一选项;
  • 丰富的失败响应:断言失败时支持重试、触发调试器、终止程序、单次忽略、永久忽略等操作;
  • 可视化提示:默认尝试弹出对话框提示用户(若平台支持),也可自定义回调函数处理断言失败;
  • 重试机制:断言失败后可重试(比如网络故障修复后重新验证条件);
  • 忽略选项:支持单次忽略或永久忽略某类无害的断言失败;
  • 统计能力:向应用程序提供所有断言失败的统计数据和详细信息;
  • 环境变量控制:自动化脚本可通过环境变量控制默认断言处理器行为;
  • 静态分析友好:Clang 静态分析会将 SDL 断言视为“恒真”(假设调试构建能检测断言错误),减少误报。

使用方式:编译调试版本时,在代码中按需添加断言检测逻辑即可!


函数

  • SDL_GetAssertionHandler:获取当前设置的自定义断言处理函数
  • SDL_GetAssertionReport:获取所有断言失败的报告(返回 SDL_AssertData 链表)
  • SDL_GetDefaultAssertionHandler:获取 SDL 默认的断言处理函数
  • SDL_ReportAssertion:手动触发断言报告(底层接口,一般无需直接调用)
  • SDL_ResetAssertionReport:清空所有断言失败的报告数据
  • SDL_SetAssertionHandler:设置自定义的断言失败处理函数(替换默认逻辑)

数据类型

  • SDL_AssertionHandler:断言处理函数的函数指针类型(自定义断言处理时需实现)

结构体

  • SDL_AssertData:存储单个断言失败的详细信息(断言表达式、文件、行号、失败次数等)

枚举

  • SDL_AssertState:定义断言失败后的处理状态(重试、终止、单次忽略、永久忽略等)

  • SDL_assert:基础断言宏(调试版本启用,发布版本禁用)
  • SDL_assert_always:强制启用的断言(无论编译模式,始终生效)
  • SDL_ASSERT_FILE:获取断言所在文件路径(内部宏)
  • SDL_ASSERT_LEVEL:定义断言启用级别(控制不同级别断言是否生效)
  • SDL_assert_paranoid:偏执级断言(仅在开启极致调试时启用,用于细粒度检测)
  • SDL_assert_release:发布版本断言(仅在发布版本中启用,检测严重问题)
  • SDL_AssertBreakpoint:触发调试器断点(断言失败时调用)
  • SDL_disabled_assert:禁用断言的占位宏(编译时会被移除)
  • SDL_enabled_assert:启用断言的核心宏(内部实现)
  • SDL_FILE:等价于 FILE,获取当前文件路径
  • SDL_FUNCTION:等价于 func,获取当前函数名
  • SDL_LINE:等价于 LINE,获取当前行号
  • SDL_NULL_WHILE_LOOP_CONDITION:检测 while 循环条件为 NULL 的断言(专用宏)
  • SDL_TriggerBreakpoint:同 SDL_AssertBreakpoint,触发调试断点

FreeBASIC 示例代码

' 引入 SDL 相关声明(需确保 FreeBASIC 已链接 SDL 库)
#Include "SDL.bi"

' 自定义断言处理函数示例
Function CustomAssertHandler Cdecl (ByVal data As SDL_AssertData Ptr, ByVal userdata As Any Ptr) As SDL_AssertState
    ' 打印断言失败详情
    SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "断言失败:")
    SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "  文件:%s", data->file)
    SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "  行号:%d", data->line)
    SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "  函数:%s", data->function_)
    SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "  表达式:%s", data->condition)
    SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "  失败次数:%d", data->trigger_count)

    ' 这里返回“重试”,也可根据需求返回 SDL_ASSERT_ABORT/SDL_ASSERT_IGNORE 等
    Return SDL_ASSERT_RETRY
End Function

' 主程序示例
Dim As Integer testValue = -1

' 设置自定义断言处理器
SDL_SetAssertionHandler(@CustomAssertHandler, NULL)

' 示例1:基础断言(调试模式生效)
SDL_assert(testValue > 0)  ' testValue=-1,断言失败

' 示例2:始终生效的断言
SDL_assert_always(testValue <> 0)  ' 即使发布版本也会触发

' 示例3:发布版本断言(仅在 release 模式生效)
SDL_assert_release(testValue < 100)  ' 表达式为真,断言通过

' 示例4:获取并打印断言报告
Dim As SDL_AssertData Ptr report = SDL_GetAssertionReport()
If (report <> NULL) Then
    SDL_LogInfo(SDL_LOG_CATEGORY_ASSERT, "断言失败总数:%d", report->trigger_count)
    SDL_ResetAssertionReport()  ' 清空报告
End If

' 恢复默认断言处理器
SDL_SetAssertionHandler(SDL_GetDefaultAssertionHandler(), NULL)

评论一下?

OωO
取消