compiler - c++14
Construya std:: error_code desde errno en POSIX y GetLastError() en Windows (2)
Eso es un problema de calidad de implementación. Se confía en el objeto estático const devuelto por std::system_category()
para realizar el mapeo de la enumeración de código de error nativo de la plataforma a la enumeración estándar std::error_condition
. En 17.6.5.14, el valor de los códigos de error [value.error.codes] :
Se recomienda que las implementaciones para sistemas operativos que no se basan en POSIX definan valores idénticos a los valores del sistema operativo.
Puede ver en http://www.boost.org/doc/libs/1_46_1/libs/system/src/error_code.cpp cómo Boost realiza el mapeo; cualquier biblioteca estándar suministrada por su proveedor de compiladores para su uso en Windows debería hacer algo similar.
El comportamiento deseado está cubierto en 19.5.1.5p4, describiendo system_category().default_error_condition(int ev)
:
Si el argumento
ev
corresponde a unposv
valor de POSIX errno, la función devolveráerror_condition(posv, generic_category())
. De lo contrario, la función devolveráerror_condition(ev, system_category())
.
Así, por ejemplo, error_code(ERROR_FILE_NOT_FOUND, std::system_category()).default_error_condition()
invocará std::system_category().default_error_condition(ERROR_FILE_NOT_FOUND)
std::error_condition(std::no_such_file_or_directory, std::generic_category())
.
Mi pregunta: ¿Cuál es la forma correcta de construir instancias std::error_code
partir de valores errno
en POSIX y GetLastError()
en Windows para que las instancias puedan compararse con los valores conocidos de std::errc
?
La explicación más larga: mi objetivo es agregar una instancia std::error_code
a un objeto de excepción hecho por sí mismo que funciona en sistemas POSIX y Windows de una manera C ++.
En mi aplicación multiplataforma, estoy usando una jerarquía de clase de E / S de creación propia que usa POSIX fopen()
y las llamadas de Windows CreateFile()
para abrir / crear archivos. Si eso falla, se open_error
excepción genérica, open_error
hecha por open_error
misma (se deriva de std::exception
, sí, pero no es una de las clases de excepción predefinidas de C ++). Estoy tratando de extender esta excepción bastante simple con un código de error; para ser más precisos con el std::error_code
C ++ 11 si entendí correctamente.
Mi problema es cómo construir un objeto de este tipo desde errno
(en el caso POSIX) o GetLastError()
(en el caso de Windows). Para POSIX, por lo que he entendido, puedo usar errno
en el constructor de std::error_code
, por ejemplo:
std::error_code ec(errno, std::generic_category());
Y esa ec
debe ser comparable a los valores conocidos de std::errc
.
Para Windows se puede hacer una llamada similar, por supuesto:
std::error_code ec(::GetLastError(), std::generic_category());
Pero no estoy seguro de si los valores devueltos por GetLastError()
corresponden bien con las constantes conocidas de std::errc
. He leído en la biblioteca del sistema de Boost que hacen para la implementación de Boost de error_code
, pero estoy preguntando sobre la implementación std
, no sobre la de Boost.
Por favor, no aconseje cambiar al uso de flujos de C ++ para acceder a archivos. Me encantaría, pero refactorizar la mitad de mi código no es algo que me gustaría hacer en este preciso momento.
Esta es una pregunta antigua, pero realmente no he encontrado una buena respuesta en SO. La respuesta aceptada me confunde un poco, ya que parece dar un error_condition
lugar de un error_code
. Me he decidido por lo siguiente en POSIX:
std::error_code error_code_from_errno(int errno_code) {
return std::make_error_code(static_cast<std::errc>(errno_code));
}
Esto siempre me da la categoría correcta (genérico o sistema). He tenido problemas en el pasado donde los códigos de error con el mismo código errno se compararon con no iguales porque uno tenía una categoría generic_category
y la otra una categoría de sistema.