Si tengo una función que devuelve algún tipo de puntero, compruebo si hay errores estableciendo el retorno a NULL en caso de error.Error al verificar una función que devuelve un int
char *foo(void) {
//If stuff doesn't go okay
return NULL;
}
char *bar = foo();
if(!bar) return 1;
Esto funciona muy bien porque sé que en tales casos nunca intentaré devolver NULL.
Sin embargo, a veces tendré funciones que devuelven enteros (en este caso, estoy leyendo entradas de un archivo de configuración). Sin embargo, el problema es que ahora no hay forma de verificar el valor devuelto por errores porque cualquier valor (incluido 0) podría ser genuino.
Un par de soluciones:
- incluir un parámetro de código de error en la función
- devolverá un código de error e incluyen un puntero int como un parámetro
El problema con estos dos es que tengo un conjunto de funciones que hacen lo mismo pero para diferentes tipos y quiero mantener una interfaz regular para que se puedan usar de la misma manera.
¿Existe alguna otra solución que no implique cambiar la interfaz a la función? ¿Cuál es la forma más común de lidiar con esta situación?
elegido la solución
Gracias por todos sus pensamientos y respuestas sobre esto.
Al final, decidí que si una función está destinada a devolver algunos datos, solo se puede devolver un error a través de un parámetro de error. De lo contrario, el error se devuelve directamente.
Elegí esta raíz porque generalmente encontré que al devolver formas de datos más complejas, el número de errores potenciales casi siempre era mayor que 1. Esto significaba que usar NULL como la única fuente de datos de error era poco práctico, ya que significaba que no había forma de determinar cuál era el error en realidad. Con funciones que devuelven datos como un int, también se volvió imposible distinguir múltiples códigos de error diferentes de los datos válidos.
Lo mismo no es cierto, por supuesto, para las funciones que realmente no devuelven ningún dato en cuyo caso soy libre de usar el valor de retorno como un código de error.
También me gusta el hecho de que el patrón anterior hace una clara distinción entre funciones que devuelven datos y funciones que no.
Variable global puede hacerse mundial por hilo (TLS en Win32). – ruslik
@ruslik: también puede usar TLS (almacenamiento local de subprocesos) en sistemas Unix; sin embargo, aún tiende a ser menos que completamente satisfactorio. –
Sé que están disponibles en la mayoría de las plataformas, pero yo solo conocía el nombre de Windows. 'GetLastError()' usa este enfoque. – ruslik