Skip to content

C++ 原生边界排错:符号、释放器与异常政策 ​

前置:extern C、unique_ptr自定义删除器和异常展开。排查用到的scan.h与main.cpp在RAII宿主完整工程。

示例未执行;下文现象与检查条件用于源码推演。

专题入口:C++ C ABI 边界:链接、不透明句柄与错误值 · C++ 原生资源所有权:接管、析构与借用 · C++ 完整实践:RAII 宿主连接 POSIX C 库 · C++ 原生边界排错:符号、释放器与异常政策

C++链接C库出现undefined reference怎么查 ​

C++链接C库出现undefined reference怎么查:先确认库确实包含 scan.c 的定义、宿主包含同一个 scan.h,再检查架构、链接命令与名称修饰。把头声明随意复制到 main.cpp 可能丢失 extern C 或参数类型,造成编译可过但链接失败甚至调用协议不匹配。

头文件缺失属于预处理/编译问题;undefined reference 属于链接;启动后坏指针是运行时契约问题。不能把这三类错误都归咎于“库版本不对”。优先回到 CMake 中两种语言的分离编译与目标依赖。

C++句柄重复释放或崩溃怎么查 ​

C++句柄重复释放或崩溃怎么查:为每个句柄画出唯一拥有者和每次销毁点,检查是否同时手动 scan_destroy 和自动删除器清理。由 C 库 calloc 创建的对象不能用 delete;即使用 free 释放外壳也遗漏路径和 mutex 清理。必须配库提供的删除器。

把 get 返回值构造成第二个 unique_ptr 同样造成双拥有者;对象析构后缓存的借用指针也失效。ASan 可以帮助定位已发生的问题,但调用边界的所有权规则必须先明确。

C++把整个C包装器设为noexcept会怎样 ​

C++把整个C包装器设为noexcept会怎样:check 本来会抛 system_error;如果把调用它的整个业务函数标 noexcept,异常离开时会触发 terminate,main 的 catch 无法恢复。noexcept 是对外承诺,不是“请编译器忽略错误”的开关。

只让真正不通过异常失败的删除器保留 noexcept,业务失败继续由宿主捕获。若未来实现 C 可调用入口,必须在入口内捕获并返回错误码;给入口加 noexcept 而不捕获,只会把本可报告的错误变为进程终止。

C++升级C库后还能否直接复用旧产物 ​

C++升级C库后还能否直接复用旧产物:本项目只承诺源码层边界设计,ABI 兼容仍取决于符号、调用约定、参数布局和运行库。改公开参数或结构、跨架构复制产物都会破坏兼容;不透明句柄减少布局暴露,不能自动解决所有变化。

当前选择同工具链全量重建静态库和宿主。若将来发行动态库,应制定版本化接口和兼容测试,再决定哪些变更允许替换;不能以“extern C 没有名称修饰”为由跨平台直接复用旧库。

独立练习 ​

链接失败与删除器错误分别在哪个阶段出现?给check外层加noexcept是否能改善错误报告?

先写出状态和资源归属,再对照答案;这些是推演练习,没有执行示例。

参考解答与检查条件

符号解析失败在链接,删除器错误在运行资源清理。noexcept会让逃出函数的system_error触发terminate,损失main捕获机会;应保持业务可抛而析构不抛。它不会把数组越界等未定义行为自动转换成异常。

资料与适用边界 ​

2026-10-17 核对 Linux read 手册、write 手册、close 的平台差异、pthread_create、pthread_join 与 POSIX mutex 规范镜像。Linux 手册中的实现差异不直接推广为 macOS 实测结果。The Open Group 的 POSIX 页面本次抓取被拒绝,不记为已成功核读。线程依赖的目标表达参考 CMake 3.20 FindThreads,没有执行它来探测本机。

C++ 链接与拥有关系参照 cppreference language linkage、unique_ptr;中文核对 Microsoft extern 说明,仅引用语言链接概念,不套用其 Windows 编译开关。文章采用独立组织的边界与失败推演,外链用于溯源,必要答案已在正文。

继续阅读