何时使用strerror方法?Boost文件系统错误处理相关疑问
问题背景
近期发现一段遗留代码,在文件操作失败时使用strerror()而非异常对象排查原因,代码如下:
try { boost::filesystem::path src(...); boost::filesystem::path dst(...); boost::filesystem::copy_file(src, dst); } catch (const boost::filesystem::filesystem_error& ex) { std::cout << "Failed to copy files. " << strerror(errno) << std::endl; }
在硬盘已满导致文件复制失败的场景中,strerror()返回"No Error",但异常对象给出了正确的"There is not enough space on the disk"错误信息。修改代码前想了解以下三个问题:
- 是否只有C运行时库会向strerror注册错误?
- 是否存在strerror比文件系统异常提供更优错误信息的场景?
- 若未直接调用C运行时函数,是否还有理由使用strerror()?
使用环境为Windows和Linux下的Boost 1.71。
问题解答
1. 是否只有C运行时库会向strerror注册错误?
strerror()是C标准库函数,它仅能解析C运行时(CRT)设置的errno值。Boost Filesystem这类库在实现时,可能直接调用系统原生API(比如Windows的CopyFileW、Linux的copy_file系统调用),这些操作触发的错误码并不会同步到errno——只有当库明确调用CRT函数并触发错误时,errno才会被正确设置。像你遇到的磁盘满场景,Boost直接捕获了系统API的错误码,没有更新errno,所以strerror()返回了无效的"No Error"。
2. 是否存在strerror比文件系统异常提供更优错误信息的场景?
几乎不存在。Boost Filesystem的filesystem_error异常本身封装了系统原生错误码和上下文相关描述(比如涉及的源/目标文件路径),而strerror()只能返回通用的错误字符串,没有任何上下文信息。反过来,只有当你直接调用CRT的文件操作函数(如fopen、memcpy)触发错误时,strerror()的信息才和errno匹配,但这种场景下若使用异常,也是开发者自行抛出,信息全面性远不如Boost内置的异常。
3. 若未直接调用C运行时函数,是否还有理由使用strerror()?
没有。如果代码中没有直接调用CRT的文件/系统操作函数,errno的值完全不可靠——它可能是之前某个无关操作遗留的,也可能根本没被当前操作设置。Boost Filesystem的异常已经提供了完整的错误信息:通过ex.what()可以获取带文件路径的完整描述,通过ex.code()可以获取对应系统的错误码,完全覆盖strerror()能提供的信息,且准确性更高。
技术建议
建议直接替换遗留代码,使用异常对象提供的信息,跨平台场景下(Windows/Linux)都能得到准确、带上下文的错误提示:
try { boost::filesystem::path src(...); boost::filesystem::path dst(...); boost::filesystem::copy_file(src, dst); } catch (const boost::filesystem::filesystem_error& ex) { std::cout << "Failed to copy files. " << ex.what() << std::endl; // 若需要获取系统原生错误码,可使用以下代码 // std::cout << "Error code: " << ex.code().value() << std::endl; }
内容的提问来源于stack exchange,提问作者LarsA

