2011-01-21 13 views
42

C'è una differenza tra queste due affermazioni all'interno di una funzione?Le parentesi intorno al risultato sono significative in una dichiarazione di reso?

bool returnValue = true; 

//Code that does something 

return(returnValue); 

e questo?

bool returnValue = true; 

//Code 

return returnValue; 

Il primo ha parentesi intorno a returnValue.

+10

Prepararsi per alcuni badge. Stranamente, queste domande * sempre * ottengono il maggior numero di visualizzazioni. –

+2

Benvenuti in Stack Overflow, Jose. Si prega di prendere nota della modifica che ho apportato alla tua domanda. In particolare menziona il cambiamento tra i due blocchi di codice, che salva i lettori dalla frustrazione di dover giocare [individuare la differenza] (http://www.spotthedifference.com/) con il tuo codice. Aiuta anche le persone a riconoscere quando una differenza era intenzionale invece di un semplice errore di battitura (come 'boo'). –

+0

Grazie Rob, hai colto con successo lo spirito della domanda. In Essence mi chiedevo se il compilatore avesse fatto qualcosa di speciale (come provare a valutare prima l'espressione) o se lo ha semplicemente ignorato. –

risposta

63

C++ 14 aggiunge una frangia caso in cui le parentesi attorno a un valore di ritorno possono alterare la semantica. Questo snippet di codice mostra due funzioni dichiarate. L'unica differenza è tra parentesi attorno al valore di ritorno.

int var1 = 42; 
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1) 
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1)) 

Nei primi func1 restituisce un int e nel secondo func1 restituisce un int&. La differenza di semantica è direttamente correlata alle parentesi circostanti.

L'identificatore auto nella sua forma più recente è stato introdotto in C++ 11. Nella C++ Language Spec è descritto come:

Specifica che il tipo di variabile che viene dichiarata sarà automaticamente dedotto dal suo inizializzatore. Per le funzioni, specifica che il tipo di ritorno è un tipo ritorno trascinamento o sarà dedotto dalle istruzioni return (dal C++ 14)

Oltre C++ 11 introdotto il decltype specificatore che è descritto nella C++ Language Spec:

ispeziona il tipo dichiarato di un'entità o interroga il tipo restituito di un'espressione.

[snip]

  1. Se l'argomento è il nome di un oggetto unparenthesised/funzione o è un'espressione member (object.member o pointer-> utente registrato), allora il decltype specifica la tipo dichiarato dell'entità specificata da questa espressione.

  2. Se l'argomento è qualunque altra espressione di tipo T, allora

    a) se la categoria valore di espressione è xValue, allora il decltype specifica T & &

    b) se la categoria valore di espressione lvalue, allora il decltype specifica T &

    c) altrimenti, decltype specifica T

.210

[snip]

noti che se il nome di un oggetto viene parentesi tonde, diventa espressione lvalue, così decltype (arg) e decltype ((arg)) sono spesso differenti tipi.

In C++ 14 la possibilità di utilizzare decltype(auto) stato permesso per i tipi di funzione di ritorno. Gli esempi originali sono dove la differenza semantica con le parentesi entra in gioco. Rivisitare le originali esempi:

int var1 = 42; 
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1) 
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1)) 

decltype(auto) permette il tipo di ritorno finale nella funzione di dedurre dall'entità/espressione return. Nella prima versione return var1; equivale a restituire il tipo decltype(var1) (un tipo di ritorno int dalla precedente regola 1) e nel secondo caso return (var1); è lo stesso di decltype((var1)) (un tipo di ritorno int & dalla regola 2b).

Le parentesi restituiscono il tipo int& anziché int, quindi una modifica della semantica. Morale della trama - "Non tutte le parentesi su un tipo di reso sono uguali"

+0

L'istruzione return senza parentesi è ancora un'espressione lvalue, giusto? A meno che non sia trattato come xvalue in quello scenario. Puoi spiegare la categoria di valore del rendimento senza parentesi? –

+0

L'istruzione return restituisce una lettura dell'espressione immessa in essa, cioè cattura un valore dall'espressione che contiene e lo restituisce. Non restituiamo mai un lvalue. Potrebbe essere possibile che qualche compilatore abbia un bug che corrisponde alla descrizione che tu dai qui, e per i motivi che fornisci qui, ma non dovrebbe mai essere il caso che 'return (x); 'sia equivalente a' return & x; ', né dovrebbe essere possibile per ottenere un ritorno del valore di x ma con il riferimento al tipo di x. –

11

Sì, si ritorna un bool, mentre l'altro un boo ...


Dopo la modifica:

no, sono la stessa cosa.

+1

Questo è un errore credo. –

+0

Grazie per avermelo fatto notare. –

+0

+1 per risposta con risposta divertente modificata;) – BlackBear

0

Nessuna differenza !!

Le persone utilizzano la parentesi se è coinvolta un'espressione complessa.

BTW return è un'istruzione non una funzione.

+0

Più persone usano le parentesi se sono neofiti di C .. –

5

Non c'è differenza.

Uno dei motivi per utilizzare le parentesi sarebbe se si volesse valutare un'espressione prima di tornare ma nel proprio esempio non ci sarebbe alcun motivo. Vedere:

Parenthesis surrounding return values

per ulteriori discussioni.

+2

Anche se con un'espressione complicata, queste parentesi non causano ancora un comportamento diverso. Semplicemente rendono il significato più ovvio (soggettivamente!) Ai lettori umani. – aschepler

+0

@Karl "Un motivo per usare la parentesi sarebbe se volessi valutare un'espressione prima di tornare" Puoi fare un esempio di questo? –

+0

@ChrisMiddleton No, perché il reclamo non ha senso qui come in quel thread. Non c'è alcuna differenza funzionale tra 'return m * x + c' e' return (m * x + c) 'o' return ((m * x) + c) 'o ecc. - e non ha alcun aspetto sia meglio che più intuitivo, se me lo chiedi. –

2

No, non ci sono differenze nel codice.

2

Presumo boo è un errore di battitura, e si chiedono se c'è una differenza tra

return expr; 

e

return(expr); 

La risposta è no.

3

AFAIK, niente è diverso.

In C++, le espressioni possono avere il formato: expr o (expr). Quindi, quest'ultimo è un'espressione con più digitazioni. Per ulteriori informazioni su questo, fare riferimento a a grammar (cercare "espressione").

+0

David, grazie per il link.Ho la grammatica nel libro C++ di Stroustrup, ma (per pigrizia credo) non la guardo più di tanto, ora che l'ho inserito nel mio browser posso farvi riferimento più spesso. –

3

Le parentesi nell'esempio superiore sono superflue; sono effettivamente ignorati.

Sarebbe lo stesso come qualcosa di simile ...

int x = (5); 

La parentesi qui vengono ignorate pure.

+0

Beh, tecnicamente, non sono * ignorati *, semplicemente non hanno alcun effetto sul valore dell'espressione. –

+0

@John: * efficacemente * ignorato. :) – James

+3

+1 ... questa è l'unica risposta che afferma che le parentesi sono in realtà * ridondanti * e mostra che il loro utilizzo è un po 'stupido. –

1

No, non c'è alcuna differenza tra i due, sebbene sia possibile includere le parentesi se rende l'espressione facile da leggere e cancellare.

+0

... ma non lo fa mai. Perché dovrebbe? Cosa è difficile da leggere su un'espressione non colorata? Aggiungere parentesi mi sembra un disordine. Per quanto sembri più chiaro, la gente pensa che "return" sia un operatore avido e che "return m * x + c" potrebbe restituire "m" e scartare il resto, o cosa? –

1

Stai rallentando abusivamente il compilatore!

La presenza di una parentesi non solo rallenta la fase di preelaborazione, ma genera anche un Abstract Syntax Tree più complicato: più memoria, più computazione.


Da un punto di vista semantico? Sono esattamente identici. Se ci sono parentesi o meno l'istruzione return valuterà completamente l'espressione prima di restituirla.

+4

Il mio modo di pensare esattamente. Facendo fare al compilatore inutili lavori analizzando il disordine inutile, si sta avvicinando alla morte termica dell'universo senza una buona ragione. –

+0

Come ti senti nei bitcoin? –

1

Sono identici. Vedo la sintassi della parentesi abbastanza spesso, e chiedo sempre a chi la usa: perché? E nessuno può rispondere perché lo usano.

Per riassumere senza mezzi termini, le parentesi attorno a espressioni di ritorno vengono utilizzate da persone che non capiscono la differenza tra macro e funzioni simili a funzioni, o che sono confuse circa la precedenza degli operatori o l'ordine delle regole di valutazione in C. Non vi è alcun vantaggio nello stile di codifica dall'uso della parentesi.

Così

return value; 

è più corretto di

return (value) 

perché quest'ultimo suggerisce di non so bene cosa si sta facendo :)

-4

Entrambi sono uguali nel tuo caso.

+0

Questa risposta è sbagliata –

+0

M.M potresti spiegare il tuo commento? –

+0

se 'a' è' 5' quindi 'return a ++;' e 'return (a ++);' (che è lo stesso) restituiscono entrambi '5' –

Problemi correlati