2009-02-17 17 views
12

Después de programar en C durante varios años, me di cuenta de que he estado ignorando la convención C de devolver cero de una función para indicar el éxito. La convención me parece semánticamente incorrecta, ya que cero es, por supuesto, falso. El problema es que me gusta el nombre de funciones como is_valid_foobar(), y con el fin de acomodar la convención de 'falsos medios éxito', que tendría que ser más vaga ... que es en lugar de:¿Debo devolver los valores VERDADERO/FALSO de una función C?

if (! is_valid_foobar()) { 
    return (error); 
} 

Otros programadores escribir:

if (validate_foobar()) { 
    return (error); 
} 

Y mi aplicación se parece a:

int is_valid_foobar (int foobar) { 
    if (foobar < MAX_ALLOWED) { 
      return TRUE; 
     } 
     return FALSE; 
} 

realidad no he cogido ninguna críticas por esto en las revisiones de código. Así que estoy pensando que no es un hábito tan terrible, pero es "poco convencional". Tengo curiosidad por lo que piensa la gente.

Soy muy cuidadoso con las opciones que tomo para nombres de funciones y variables, y un comentario típico de revisión es "el código es muy claro", y además no me molesta en absoluto tener que escribir un extra ! en la parte frontal de la llamada de función. Pero ¿qué dices, oh poderosos de S.O?

Respuesta

19

yo diría que ambos son correctos, para diferentes propósitos:

Si usted está realizando un ir sencilla/no pasa la validación, por ejemplo, is_numeric(), entonces true y false funcionan muy bien.

Para algo más elaborado, el paradigma 0 == success es útil ya que permite que se devuelva más de una condición de error.

En este caso, la persona que llama puede simplemente hacer una prueba en contra de 0, o examinar las declaraciones que no sean 0 para obtener una explicación más específica de la falla. p.ej. una llamada abierta de archivo puede fallar debido a la inexistencia, permisos insuficientes, etc.

+0

Correcto, y si no le gusta usar 0 para el éxito, generalmente los marcos o plataformas proporcionan algo así como una macro/valor (el nombre interesante) ERROR_SUCCESS (junto con los nombres de código de error correspondientes) para abstraerse del numérico valores algo –

+0

Este uso también permite la formulación "if (int e = foo()) {/ * manejar errores * /};", lo que puede parecer torpe a las personas planteadas en más idiomas, pero está limpio y resbaladizo según los estándares c. – dmckee

3

No estoy seguro de que acepte que existe la convención de "devolver cero de una función para indicar el éxito".

AFAIK, la convención es que cero es falso, y todos los nonzeros son verdaderos en el caso de predicados.

Sin embargo, esta convención solo debería aplicarse a predicados obvios que devuelven booleanos (por ejemplo, verdadero/falso). Si el objetivo principal de una función no es devolver un valor booleano (por ejemplo, printf, fopen, etc.), el valor de retorno se utiliza para indicar motivos de falla y luego puede adoptar la convención de UNIX de "silencio o 0 a menos hay un problema".

En cuanto a los valores de retorno, no hay nada de malo con el uso de valores de retorno fijos, hace que todo sea más conveniente.

El gran riesgo, en mi humilde opinión, es que muchas personas declaran sus propias constantes, y cuando otros usan los mismos archivos, comienzas a tener conflictos con sus propias constantes. Así que su VERDADERO/FALSO y el conflicto con alguien más es VERDADERO/FALSO en la línea.

2

Eso no es tanto una convención C como una shell UN * X. Considere las funciones Estándar C iasalpha(), isdigit() etc. Todos devuelven un valor distinto de cero para indicar el éxito. En pocas palabras: en C 'verdadero' no es cero.

+0

+1.Además, en Unix/Linux, estas convenciones se aplican a programas (procesos separados) que se llaman y conectan entre sí, lo cual no es lo mismo que las funciones que se llaman entre sí dentro de un único programa, aunque la convención es la misma. – heltonbiker

11

La convención no es exactamente lo que usted parece pensar.Los procesos deben salir con un estado 0 para indicar el éxito, y las funciones que devuelven los códigos de error a menudo usan 0 para indicar "sin error". Pero como booleano, 0 debería significar falso y no cero significa verdadero. Utilizar 0 para boolean true lo pondrá en The Daily WTF algún día.

3

Especialmente cuando nombra su función is_foo(), las funciones de caracteres C estándar (isdigit(), isupper(), etc.) son un buen precedente para hacerlo a su manera.

3

C no tiene ningún concepto de que booleano que no sea 0 sea falso, y todo lo demás es verdadero.

La idea de devolver 0 proviene de tener un código de retorno que indica cuál es la falla. Si no está haciendo un código de retorno, no hay nada de malo en considerar 1 y 0 como verdadero y falso. Después de todo, TRUE y FALSE son simplemente typedefs para 1 y 0 en C.

Esto debería estar bien documentado, y los comentarios de su función deberían indicar explícitamente "Devuelve VERDADERO o FALSO".

También podría escribir if (is_invalid_foobar()), que podría hacer que la declaración sea fácil de entender y semánticamente correcta.

0

Es malo si te quema. Si nunca trazas ningún error a esto, diría que estás bien. Lo que es más importante, es el comentario sobre la función que comienza con "Devuelve cero para ..."

El "distinto de cero es un error" convención se utiliza cuando se trata de decir qué junto con la bandera de error.

6

Ha sido un tiempo desde que he programado C, pero creo que estamos hablando de dos tipos diferentes de funciones aquí:

  • is_foo es una función que comprueba si alguna propiedad foo y devuelve 0 (false) o no 0 (true) para indicar el valor booleano de esa propiedad. Al llamar a esas funciones, no se espera ningún estado de error (y si sucede, se mapea en uno de esos valores).
  • foo es una función que ejecuta la acción foo. Devuelve 0 en caso de éxito y un valor no 0 en caso de error.
0

para mí, de hecho la comprobación contra 0 parece más natural y optimiza el compilador de todos modos por lo que me gusta escribir por ejemplo

si (check_foo == 0) // hacer algo

0

Retorno valor por una función - convenciones para verdadero y falso o el éxito y error:

  1. una API etc. muestra éxito con valor de retorno 0 y el fracaso con el valor de retorno = valor de error distinto de cero.
  2. Si algo es cierto; funciones devuelven 1. Por ej. isStackEmpty() devolverá 1 si la pila está vacía.
0

Todavía es completamente arbitrario devolver 1 o 0. Simplemente sea consistente y si hay códigos de error, al menos comente lo que significan en alguna parte.

Cuestiones relacionadas