据我所知,处理流错误的两个选项是perror
和流异常。两种选择都是不可取的这就是原因:
PERROR
std::strerror
返回实现定义的消息。此消息在所有系统上并不总是有用
std::strerror
不是线程安全的
std::strerror
返回的指针可以无效
C库技术上已被弃用"在C ++中。几乎总是一个C ++ - 等同于。当没有潜在的C ++等价物时,我没有理由依赖POSIX和C
流异常
例外情况不适合每个程序
虽然std::strerror
有时可以提供有用的错误消息,但流永远不会提供有用的错误消息。对于f.exceptions(f.failbit)
,无论是打开文件失败还是无法解压缩,引发的异常都是std::ios_base::failure
而what()
是" basic_ios::clear
"。
SYSTEM_ERROR
用std::ios_base::failure
替换std::system_error
会产生完全相同的结果。如果我们看一下N2769: Detailed Reporting for Input/Output Library Errors (Revision 2)
,我们可以看到原因:
当抛出
ios_base::failure
例外时,实现是 鼓励提供ec
的值,以确定具体原因 为了失败。 [ 注意 - 操作产生的错误 系统通常会报告为system_category
错误 操作系统报告的错误号的错误值。 流库中出现的错误通常是 报告为error_code(ioerrc::stream, iostream_category
) - 结束 注意 ]。以上措辞只为规范性鼓励实施者做正确的事情,因而依赖于市场力量 以及实施者的良好意图,以产生有用的结果 用户。任何更强大的东西(比如改变"都会被鼓励到#34; to "将")需要更多的额外规范,超出了 LWG可以实际解决C ++ 0x的范围。
另一种选择是潜在地依赖庞大的第三方图书馆(我看着你Boost)或者手工推广它(除非你知道自己在做什么,否则你永远不想做。我正在寻找C ++标准库的方法来做到这一点。有没有?
答案 0 :(得分:1)
我不同意你的意见
perror等人是C标准库的成员,因此在技术上已弃用(*)。
即使在cplusplus.com上,如果不是官方文档来源,我也会看到errno:
C ++ 11扩展了在此标头中定义所需的基本值集...在C ++中,errno始终声明为宏,但在C中,它也可以实现为具有外部链接的int对象。
我对这些句子的理解是{C} 11中仍然考虑errno
!
我甚至可以看到以后
支持多线程的库应该在每个线程的基础上实现errno:每个线程都有自己的本地errno。这是符合C11和C ++ 11标准的库中的要求。
这意味着即使strerror()
不是线程安全的,errno
也适用于符合C ++ 11的实现。
如果您愿意,现在由您在同步函数中使用std::strerror
(例如使用互斥锁保护)来构建std::string
。但无论如何,即使strerror
上的每个文档都声明它使用了一个可以被覆盖的静态缓冲区(这就是Posix 1定义strerror_r的原因),我在perror
上找不到任何警告保护线安全。
(*)我的意见就是每当OO和模板可以提供更好的界面(iostream vs stdio.h或string vs string.h)时,C库的元素是< em>被C ++库中的其他人替换。但是当没有任何东西可以添加(cerrno,cmath,csignal等)时,C标准库中的函数只包含在C ++库中。
答案 1 :(得分:0)
POSIX有strerror_r()
,Windows有strerror_s()
。请注意,有一些名为strerror_r()
的不兼容函数,所以请使用功能测试宏。