C++ <;系统错误>;类别和标准/系统错误代码
C++11引入了C++ <;系统错误>;类别和标准/系统错误代码,c++,c++11,winapi,posix,system-error,C++,C++11,Winapi,Posix,System Error,C++11引入了标题,其中包含处理错误代码的通用系统。std::error\u code是一个元组,包含int、错误代码和对std::error\u类别的引用,该类别定义了错误域和错误代码的处理。标准库有四个类别:std::generic_category,std::system_category,std::future_category,以及std::iostream_category P>在创建 STD::Error代码> /Calp>S/Pox STD::StulyOrgRebug <
标题,其中包含处理错误代码的通用系统。std::error\u code
是一个元组,包含int
、错误代码和对std::error\u类别的引用,该类别定义了错误域和错误代码的处理。标准库有四个类别:std::generic_category
,std::system_category
,std::future_category
,以及std::iostream_category
<> P>在创建<代码> STD::Error代码> /Calp>S/Pox<代码> STD::StulyOrgRebug < /Cult> s,代码< > ErnOn> /Cord>和WiAPI错误代码:< /P>时,在哪个C++类中使用哪些类冲突?
errno
带有std::generic_category
:
errno
带有std::system\u类别
:
GetLastError()
带有std::generic\u category
:
GetLastError()
带有std::system\u类别
:
但是,errno
和GetLastError()
不能使用相同的类别,否则某些错误代码将不明确。错误代码33是一个例子,因为它既是EDOM
又是Error\u LOCK\u违规
甚至有一些地方主张为WinAPI创建一个用户自定义的类别,但我目前找不到任何关于该类别的参考。这种选择将特别痛苦
哪个类别应与errno
一起使用,哪个类别应与GetLastError()
一起使用,以便
std::error\u code::default\u error\u condition()
std::error\u code::message()
对C++标准中的底层错误代码
是否是不恰当的?
system\u类别
缔约国指出:
C++标准库中的某些函数报告错误
通过std::error\u code
(19.5.2.1)对象。那个
对象的category()
成员应返回std::system\u category()
对于源自操作系统的错误,
或引用定义的实现错误\u类别
对象查找源自其他地方的错误。实施
应为每一项定义value()的可能值
错误>类别。
[示例:对于基于POSIX的操作系统,
鼓励实现定义std::system\u category()
与POSIXerrno
值相同的值,并附加
由操作系统文档定义的值。
不基于POSIX的操作系统的实现
鼓励定义与操作参数相同的值
系统的值。对于非源于
在操作系统中,实现可能会为
关联值
不太清楚:
- Windows上的
errno
值会发生什么情况
- 来自POSIX调用的
errno
是“源于操作系统”还是仅限于非POSIX调用
通用类别
std::errc
是一个枚举,其值与C/POSIXeFobar
错误代码相同
每个enum errc
常量的值应与
上述概要中显示的
宏的值。
实现是否公开
宏未指定
生成错误代码(std::errc)
使用通用类别生成错误代码
error\u code make\u error\u code(errc e)无异常;
返回:error\u code(static\u cast(e),generic\u category())
这意味着POSIX错误代码可以与generic_category
一起使用。非POSIX值可能无法与generic_catgeory
一起正确工作。实际上,我使用的实现似乎支持它们
增强
增压系统本身
Boost文档非常简洁地介绍了此功能:
最初的提案将错误类别视为二元选择
在errno(即POSIX样式)和本机操作系统的
错误代码
此外,您还可以找到遗留声明,例如:
static const error\u category&errno\u ecat=generic\u category();
在linux\u error.hpp
中:
要在API错误后构造错误代码:error\u code(errno,system\u category())
在windows\u error.hpp中
:
要在API错误后构造错误代码:error\u code(::GetLastError(),system\u category())
在cygwin\u error.hpp
中:
要在API错误后构造错误代码:错误代码(errno,system\u category())
对于Windows,Boost对非errno
错误使用system\u类别
:
ec = error_code( ERROR_ACCESS_DENIED, system_category() );
ec = error_code( ERROR_ALREADY_EXISTS, system_category() );
ec = error_code( ERROR_BAD_UNIT, system_category() );
ec = error_code( ERROR_WRITE_PROTECT, system_category() );
ec = error_code( WSAEWOULDBLOCK, system_category() );
在亚洲
我们在ASIO中发现此类代码:
template <typename ReturnType>
inline ReturnType error_wrapper(ReturnType return_value,
boost::system::error_code& ec)
{
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
ec = boost::system::error_code(WSAGetLastError(),
boost::asio::error::get_system_category());
#else
ec = boost::system::error_code(errno,
boost::asio::error::get_system_category());
#endif
return return_value;
}
文件系统
我们在POSIX代码中找到errno
和generic_category
:
int error = ::pthread_cond_init(&cond_, 0);
boost::system::error_code ec(error,
boost::asio::error::get_system_category());
if (::chmod(p.c_str(), mode_cast(prms)))
{
if (ec == 0)
BOOST_FILESYSTEM_THROW(filesystem_error(
"boost::filesystem::permissions", p,
error_code(errno, system::generic_category())));
else
ec->assign(errno, system::generic_category());
}
在GNU libstdc中++
文件系统
我们发现errno
与generic\u类别一起
:
if (char* rp = ::realpath(pa.c_str(), buf.get())) {
[...]
}
if (errno != ENAMETOOLONG) {
ec.assign(errno, std::generic_category());
return result;
}
int ec = pthread_join(__t_, 0);
if (ec)
throw system_error(error_code(ec, system_category()), "thread::join failed");
并且不使用system\u类别
使用libstdc++
实际上,您似乎可以使用libstdc++为非POSIXerrno
使用generic\u category
:
std::error_code a(EADV, std::generic_category());
std::error_code b(EADV, std::system_category());
std::cerr << a.message() << '\n';
std::cerr << b.message() << '\n';
Libc++
我们发现errno
带有system\u类别
:
if (char* rp = ::realpath(pa.c_str(), buf.get())) {
[...]
}
if (errno != ENAMETOOLONG) {
ec.assign(errno, std::generic_category());
return result;
}
int ec = pthread_join(__t_, 0);
if (ec)
throw system_error(error_code(ec, system_category()), "thread::join failed");
但不使用通用类别
结论
我在这里找不到任何一致的模式,但显然:
- 在Windows上使用Windows错误时,您需要使用
system\u category
- 对于
errno
;generic_category