2012-10-04 20 views
8

he mi propio tipo y funciones de retorno se define así:regla general: los valores negativos o positivos para el código de error en C/C++

typedef enum xx_return_t { 
    success = 0, 
    general_error = -1, 
    specific_error = -2, 
    [...] 
} xx_return_type; 

xx_return_type generalFunction(void) { 
    if(there_was_an_error) 
     return general_error; 
} 

Sin embargo, yo soy un poco incertidumbre en los valores de tipo de error aquí; ¿cuál es la práctica estándar/mejor para los valores de los retornos de error en C/C++ - negativa o positiva?

Actualización: Gracias por sus respuestas! Estaba buscando información sobre C y C++, pero también me doy cuenta de que esto genera buenas preguntas sobre la estructura general y los métodos específicos de cada idioma (excepciones, códigos de error, declaraciones de objetos, etc.).

+0

¿Está preguntando acerca de C o C++? – Default

Respuesta

15

Esto es realmente dos preguntas totalmente diferentes (versiones C y C++) disfrazadas como una sola.

En C++ la respuesta es simple: utilice valores de retorno para ... valores de datos devueltos y use excepciones para casos de error/excepción. No utilice valores de retorno para la comprobación de errores en C++ puro (una API de biblioteca C a C++ es una historia diferente).

En C no tiene esa opción, entonces le sugiero que use 0 para el éxito y los números negativos para los códigos de error. Esto deja la flexibilidad, si se desea, para usar números positivos para obtener información adicional de éxito (por ejemplo read llamadas)

+1

¡Mejor hasta ahora! {llenador} –

+2

En cuanto a las excepciones en C++, me gustaría señalar que no significa que de repente todos los métodos deben 'throw'. Por ejemplo: 'T const * MyMap :: find (std :: string const & name);' es un método que no necesita arrojarse cuando no se encontró el nombre; solo puede devolver un puntero nulo. –

+0

Estoy de acuerdo con Matthieu. Solo se deben emitir excepciones en caso de eventos excepcionales, resultados ordinarios negativos de una búsqueda, etc.Lanzar excepciones es mucho más lento que devolver el valor de la función e incluso si no se lanza el bloque try {} catch() en sí mismo y la inclusión de todas las máquinas de manejo de excepciones hace que el programa sea más lento. – 4pie0

1

Es mejor usar 0 (cero) y no cero, por lo que también se pueden considerar booleanos. Típicamente falso es 0, y verdadero es cualquier otra cosa.

+0

Eso es lo que está haciendo y no cero puede ser negativo y positivo ... –

+1

@LuchianGrigore En realidad, está haciendo lo contrario. Como mencionaste, ambos son comunes, pero es bueno poder usar también verdadero/falso. – Brady

+0

¿Cómo llamas lo opuesto? "usando 0 y distinto de cero" en lugar de "usar cero y 0"? –

4

C++:

  1. Es una cuestión de elección, he visto tanto.
  2. ¡Utilice excepciones!
+4

"2." funciona especialmente bien para esta etiqueta 'c' ;-) –

+4

(Desearía que hubiera una opción' + 0.5' ;-)) –

+3

@ MichaelKrelin-hacker: Siempre es un problema con las preguntas de C/C++. O es C o es C++ ... –

2

No sé sobre C ...

... pero en C++ la idea es no utilizar los códigos de error, en general.

No quiero decir que deba usar excepciones, pero un código de error no es realmente muy informativo (carece de contexto, ¿cuál es el valor de FILE_NOT_FOUND cuando se desconoce el nombre del archivo?).

En los casos en que no usé excepciones, tendí a preferir los objetos de error completo. Un ejemplo podría ser:

boost::variant<File, Error> open(std::string const& filename, FileMode mode); 

donde obtendrá un archivo o un error, dependiendo de lo que esté sucediendo.

2

Hay varias convenciones para elegir:

  • utiliza Microsoft 0 = False = error durante la mayor parte de su alto nivel de API. y deje que el usuario busque el error específico con una función global GetLastError()
  • microsoft usa 0 = ok para aplicaciones de nivel inferior, como registro, audio o telefonía. todos devuelven un tipo similar a HRESULT, que contiene el código de error específico.
  • funciones POSIX que regresan un estado generalmente devuelven -1 para el error, y permiten al usuario buscar el error a través de una variable global errno
  • funciones que devuelven un puntero suele devolver NULL para el error
  • c funciones STL ++ vuelven 'fin' de estado como 'no encontrado'. errores como 'falta de memoria' se señalizan usando una excepción.

En general, es más importante que utilice su convención de forma coherente, que la convención que utiliza.

Por cierto, algunos ejemplos de cómo no hacer esto se pueden encontrar en los archivos de cabecera de Microsoft:

#define S_OK  ((HRESULT)0x00000000L) 
#define S_FALSE ((HRESULT)0x00000001L) 

También tenga cuidado de dos valores de error diferentes para HANDLE 's en las ventanas: 0 o INVALID_HANDLE_VALUE

Cuestiones relacionadas