2009-08-06 11 views
5

consideremos el siguiente ejemplo artificial:cuestión estilística, relativa a regresar vacío

void HandleThat() { ... } 

void HandleThis() 
{ 
    if (That) return HandleThat(); 
    ... 
} 

Este código funciona muy bien, y estoy bastante seguro de que es de las especificaciones válidas, pero (quizás por mi cuenta) consideran este estilo inusual , ya que la llamada parece devolver el resultado de la función, a pesar del hecho de que ambas funciones son prototipo para ser nulas.

Por lo general, yo esperaría a ver:

if (That) {HandleThat(); return;} 

cual, me siento, no deja ninguna ambigüedad en cuanto a lo que está pasando.

SO comunidad, ¿puedo obtener su opinión sobre si el estilo de codificación de devolución de datos es confuso o problemático? Tiene la sensación de un modismo; ¿Debería usar esto o evitarlo?

En general, me esforzaré por la claridad y utilizaré el segundo estilo. Por otro lado, hay una pulcritud en la primera forma que me atrae de alguna manera.

+0

En caso de que sea de su interés, mi uso real de esto es rescatar a una clase para padres bajo ciertas circunstancias. Viz: void derivedclass :: f (...) {if (fianza) return parentclass :: f (...); ...} –

Respuesta

13

Estoy de acuerdo con usted, el primer estilo es confuso porque existe la implicación de que se devuelve algún tipo de valor. De hecho, tuve que leerlo un par de veces porque de eso.

Cuando se regresa de un vacío de prototipo de función, solo se debe devolver;

+0

+1 No veo ninguna buena razón por la que alguien deba usar la primera convención cuando devuelva el vacío. – Eric

+0

De acuerdo, este último es más intuitivo y legible, definitivamente vale la pena el par de caracteres adicionales. – Amber

+1

Este último es más intuitivo y legible. Sin embargo, el primero también es muy legible, y lo que intuyes es correcto. Entonces no rompe tu intuición. –

11

Esto es probablemente un poco demasiado inteligente. Si esa línea termina a más de un par de líneas de la parte superior de la función, será confuso. También significa que el programador mirar el código necesitará correlacionar la

return HandleThat(); 

con el tipo de retorno void y averiguar la inteligencia antes de que realmente entienden el código. Cuando haces más de una cosa en una rama if/else, deberías usar llaves y poner los pasos en diferentes líneas. Toma más espacio, pero es más fácil de entender:

if (That) { 
    HandleThat(); 
    return; 
} 
3

Nunca antes visto.

Tiene la ventaja de parecer un idioma común para los tipos de retorno no nulo, por lo que se lee muy fácilmente ...

no cambiaría a menos que alguien pueda demostrar que no es válido.

4

Las reglas del lenguaje C dicen que si una función declarada como return void intenta devolver una expresión, la expresión no será evaluada.

http://c0x.coding-guidelines.com/6.8.6.4.html

+0

Ambos estilos generan resultados idénticos. Para este código: void a() {printf ("World! \ N");} void b() {printf ("Hola"); return a(); } obtienes Hello World como se esperaba. –

+1

He verificado que con optimizaciones completas y stripping usando GCC 4.0 –

+0

creo que su comportamiento indefinido técnicamente. – sylvanaar

2

creo que la primera versión se permite principalmente a facilitar la programación de la plantilla. Si HandleThat devolvió un tipo T que podría o no ser nulo, es conveniente usar la primera versión.

Pero en los casos "normales", la segunda versión es más clara y preferiría eso.