2009-08-06 13 views
5

Si consideri il seguente esempio inventato:questione stilistica relativo ritorno vuoto

void HandleThat() { ... } 

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

Questo codice funziona bene, e sono abbastanza sicuro che è spec-valida, ma io (forse da solo) considerano questo stile insolito , poiché la chiamata sembra restituire il risultato della funzione, nonostante il fatto che entrambe le funzioni siano prototipate per essere annullate.

In genere, mi sarei aspettato di vedere:

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

che, ritengo, lascia alcuna ambiguità su ciò che sta succedendo.

SO community, posso avere la tua opinione sul fatto che lo stile di codifica return-void sia confuso o problematico? Ha la sensazione di un idioma; dovrei usare questo o evitarlo?

In generale, mi piacerebbe fare chiarezza e utilizzare il secondo stile. D'altra parte, c'è una precisione nella prima forma che mi attira in qualche modo.

+0

Nel caso in cui sia di interesse, il mio uso effettivo di questo è di eseguire il rilascio su una classe di genitore in determinate circostanze. Viz: void derivedclass :: f (...) {if (bail) return parentclass :: f (...); ...} –

risposta

13

Sono d'accordo con te, il primo stile è confuso perché c'è l'implicazione che una sorta di valore viene restituito. In effetti ho dovuto leggerlo un paio di volte perché di quello.

Al ritorno da una funzione prototipo di vuoto, dovrebbe essere restituito;

+0

+1 Non riesco a vedere nessuna buona ragione per cui qualcuno dovrebbe usare la prima convenzione quando restituisce nulla. – Eric

+0

D'accordo, quest'ultimo è più intuitivo e leggibile - sicuramente vale la pena di un paio di caratteri extra. – Amber

+1

Quest'ultimo è più intuitivo e leggibile. Tuttavia, il primo è anche molto leggibile e ciò che intendi è corretto. Quindi non infrange il tuo intuito. –

11

Questo probabilmente è solo un po 'troppo intelligente. Se quella linea finisce più di un paio di righe dalla parte superiore della funzione, sarà confusa. Significa anche il programmatore guardando il codice sarà necessario correlare la

return HandleThat(); 

con il tipo di ritorno void e capire la bravura, prima che realmente capire il codice. Quando stai facendo più di una cosa in un ramo if/else, dovresti usare le parentesi e mettere i passaggi su linee diverse. Prende più spazio ma è più facile da capire:

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

Mai visto prima.

ha il vantaggio di guardare come un idioma comune per i tipi di ritorno non-vuoto, in modo che legge molto facilmente ...

non vorrei cambiarlo a meno che qualcuno può dimostrare che non è valido.

4

Le regole del linguaggio C dicono che se una funzione dichiarata come restituzione void tenta di restituire un'espressione, l'espressione non verrà valutata.

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

+0

Entrambi gli stili generano risultati identici. Per questo codice: void a() {printf ("World! \ N");} void b() {printf ("Hello,"); return a(); } ottieni Hello World come previsto. –

+1

Ho verificato che con le ottimizzazioni complete e la rimozione con GCC 4.0 –

+0

penso che il suo comportamento non definito tecnicamente. – sylvanaar

2

credo che la prima versione è principalmente consentito per facilitare la programmazione modello. Se HandleThat ha restituito un tipo T che potrebbe o non potrebbe essere vuoto, è conveniente utilizzare la prima versione.

Ma nei casi "normali", la seconda versione è più chiara e preferirei quella.