我在C++ 11中阅读了一系列关于新<system_error>标题的深思熟虑的博客文章.它表示标头定义了一个error_code类,它表示操作(例如系统调用)返回的特定错误值.它表示标头定义了一个system_error类,它是一个异常类(继承自runtime_exception)并用于包装error_codess.
我想知道的是如何将系统错误实际转换errno为一个,system_error所以我可以抛出它.例如,POSIX open函数通过返回-1和设置来报告错误errno,因此如果我想抛出异常,我应该如何完成下面的代码?
void x()
{
fd = open("foo", O_RDWR);
if (fd == -1)
{
throw /* need some code here to make a std::system_error from errno */;
}
}
Run Code Online (Sandbox Code Playgroud)
我随机试了一下:
errno = ENOENT;
throw std::system_error();
Run Code Online (Sandbox Code Playgroud)
但是在what()调用时,结果异常不返回任何信息.
我知道我可以做throw errno;但我想以正确的方式使用新的<system_error>标题.
有一个构造函数system_error需要一个单独error_code的参数,所以如果我可以转换errno为error_code那么其余的应该是显而易见的.
这似乎是一个非常基本的东西,所以我不知道为什么我找不到一个好的教程.
我在ARM处理器上使用gcc 4.4.5,如果这很重要的话.
我的问题:std::error_code从errnoPOSIX和GetLastError()Windows上的值构造实例的正确方法是什么,以便可以将实例与众所周知的值进行比较std::errc?
更长的解释:我的目标是将一个std::error_code实例添加到一个自制的异常对象,该对象以C++ 11方式在POSIX和Windows系统上运行.
在我的跨平台应用程序中,我使用的是自制的I/O类层次结构,它使用POSIX fopen()和Windows CreateFile()调用来打开/创建文件.如果失败open_error则抛出一个泛型的自制异常(它来自std::exception,是的,但它不是C++的预定义异常类之一).我试图用错误代码扩展这个相当简单的异常; std::error_code如果我理解正确的话,用C++ 11来更精确.
我的问题是如何从errno(在POSIX情况下)或GetLastError()(在Windows情况下)构造这样的对象.对于POSIX,据我所知,我可以简单地使用errnoin std::error_code的构造函数,例如:
std::error_code ec(errno, std::generic_category());
Run Code Online (Sandbox Code Playgroud)
这ec应该与众所周知的价值相当std::errc.
对于Windows,可以进行类似的调用,当然:
std::error_code ec(::GetLastError(), std::generic_category());
Run Code Online (Sandbox Code Playgroud)
但是我不确定GetLastError()map 返回的值是否很好地映射到了众所周知的常量std::errc.我在Boost的系统库中读过他们为Boost实现的内容error_code,但我要问的是std实现,而不是关于Boost的实现.
请不要建议切换到使用C++流进行文件访问.我很乐意,但重构我的一半代码并不是我此刻想做的事情.
我知道我们可以使用
perror()
Run Code Online (Sandbox Code Playgroud)
在C中打印错误.我只是想知道是否有一个C++替代品,或者我是否必须在我的程序中包含它(因此stdio.h).我试图避免尽可能多的C函数.
谢谢!
如果我调用通过GetLastError报告错误的Win32函数,例如RegisterClassEx,如何为该错误抛出std :: system_error?
C++ 0x有两个预定义的error_category对象:generic_category()和system_category().从我到目前为止所理解的,system_category()应该用于操作系统返回的错误,并且generic_category()应该用于找到的通用值std::errc,它们对应于errno值.
但是,在类Unix系统上应该做些什么,其中errno值是操作系统返回的错误?我应该使用system_category()(在非类Unix系统上会出错,需要#ifdef),还是应该使用generic_category()(对于非标准errno值,类Unix系统会出错)?
我试图了解在调用errno在 Linux上设置的 C 函数时应该使用哪个类别。
我不确定所有可能的错误代码都是由 POSIX 定义的,所以我很想使用system_category.
但是我喜欢稍后在我的代码中处理通用条件,所以我想做这样的事情:
std::error_code ec;
some_func(some_path, ec);
if (ec) {
if (ec == std::errc::file_exists) {
// special handling
}
return ec;
}
Run Code Online (Sandbox Code Playgroud)
要在 中设置错误代码some_func(),我希望像这样进行:
ec.assign(EEXIST, std::system_category());
Run Code Online (Sandbox Code Playgroud)
主要基于此讨论:
Run Code Online (Sandbox Code Playgroud)std::error_code ec; if(-1 == open(...)) ec = std::error_code(errno, std::system_category()); // To test using portable code if(ec == std::errc::no_such_file_or_directory) ... // To convert into nearest portable error condition (lossy, may fail) std::error_condition ec2(ec.default_error_condition())
但是,在 Linux 上,使用 GCC …
c++ ×5
c++11 ×5
errno ×1
error-code ×1
exception ×1
linux ×1
printing ×1
system-error ×1
unix ×1
winapi ×1