2010-07-01 14 views
8

solito auto-generata funzione C++ "principale" ha alla fineParentesi attorno a 0 in "ritorno (0);" dichiarazione nella funzione 'principale' - a cosa servono?

return (0); 

o

return (EXIT_SUCCESS); 

Ma perché non ci sono parentesi a dichiarazioni di cui sopra? È legato al linguaggio C o qualcosa del genere?

// EDIT

So che questo è corretto, ma qualcuno ha messo queste staffe per un motivo. Per quale motivo?!

+0

Quale strumento genera questo codice? Il ritorno da 'main' non è affatto necessario. – Philipp

+0

Netbeans, Code :: Blocks, Eclipse ... – adf88

+0

Sì, hai ragione, EXIT_SUCCESS, corretto. – adf88

risposta

10

Non sono necessari (anche in c). Penso che alcune persone li usino per rendere il "ritorno" più simile a una chiamata di funzione, pensando che sia più coerente.

Modifica: È probabile che il generatore lo faccia per le proprie ragioni. Potrebbe essere più sicuro o più facile per farlo funzionare in questo modo.

+0

Ma qual è il punto se si trova nel codice generato? Ho pensato ad una qualche forma di protezione. – slaphappy

+3

Forse il codice generato potrebbe contenere un punto e virgola.Quindi la versione parentesi causerebbe un errore del compilatore, mentre la versione non parentesi fallirebbe in modo silenzioso o produrrebbe semplicemente un avvertimento. – Philipp

+0

Trovo che ci siano alcune cose che non mi piacciono del particolare generatore di codice a cui probabilmente stai facendo riferimento ... ad es. aprendo parentesi graffe sulla riga successiva. In #defines, è sempre opportuno inserire parentesi attorno alle espressioni, ad es. '#define X (x) (x-2x)' dato che di solito aiuta quando fai '3 * X (2)'. Non riesco a pensare a nessuna buona ragione per fare questo per i ritorni. – sje397

5

Come qualsiasi espressione valida può essere passata al ritorno, è possibile aggiungere queste parentesi se lo si desidera. E 'come fare questo:

int i = (0); 

È possibile nidificare un'espressione nel maggior numero di parentesi come ti:

return (((((0))))); 
+6

Puoi anche fare: return (42 - 42); – nas

2

Quelli non sono necessari. Forse provengono dalla tendenza a preferire più parentesi a meno parentesi when writing macros.

Poiché si menziona il codice generato automaticamente, potrebbe accadere che il codice utilizzato per generare macro sia stato scritto riutilizzando il codice per generare macro o da una persona che pensava che più parentesi non avrebbero danneggiato, ma meno parentesi possono essere fatali.

9

Ma perché ci sono parentesi in sopra dichiarazioni? È legato alla lingua C o qualcosa del genere?

No. Per quanto posso dire, C non ha mai richiesto le parentesi per le dichiarazioni di reso. Questo sembra essere stato il caso anche prima del primo standard ANSI C.

Questa è in realtà una domanda molto interessante, tuttavia, come ho visto lo stile prevalente tra alcuni programmatori C.

Penso che l'ipotesi più probabile sul perché questo stile sia dovuto al fatto che tutte le altre istruzioni di ramificazione (per, while, if, switch) richiedono parentesi attorno alle espressioni. Le persone potrebbero non essere a conoscenza del fatto che potrebbero omettere le parentesi per le dichiarazioni di reso o ne erano consapevoli, ma volevano ottenere un aspetto più uniforme del loro codice.

L'operatore ternario?: È un'eccezione in quanto è un operatore e non richiede parentesi attorno all'espressione condizionale, tuttavia le persone spesso scrivono tra parentesi anche se è necessario. Alcuni potrebbero trovare che serve a 'raggruppare' un'espressione in una singola unità visivamente.

La mia seconda ipotesi è che questo stile fosse influenzato da altre lingue popolari all'epoca.Tuttavia, al momento le alternative procedurali e popolari come Pascal non richiedevano quella sintassi (Pascal non aveva nemmeno i valori di ritorno nel senso C ma solo i parametri di output) quindi se questo è il caso, non sono a conoscenza di alcun linguaggio particolare da cui è nato questo stile.

[Soggettivo] Preferisco gli stili che richiedono la minima quantità di decorazione superflua nel codice, sia che si tratti di convenzioni di denominazione o di come formattare o se utilizzare parentesi aggiuntive laddove non necessario. Trovo che una tale decorazione tenda ad essere una questione di preferenze personali e innamorarsi di un modo di decorare il codice significa semplicemente che un giorno dovrai affrontare un modo completamente diverso (a meno che non lavori rigorosamente da solo, nel qual caso Ti invidio). [/ Soggettivo]

+0

Hai sottolineato molto bene che questo può essere un ricordo dei tempi passati. Se solo qualcuno potesse confermare che ... Se questo è un caso di stile di codifica e decorazione di codice extra, allora perché non possiamo trovare questo stile da nessun'altra parte (almeno io)? Hmm, forse questo è un relitto, una specie di tradizione? – adf88

+0

@ adf88 Assumerei così. return expr; e ritorno (expr); sarà sempre lo stesso, comunque. Non potrebbe esserci un caso in cui valuterebbe un risultato diverso o non riuscisse a costruire senza le parentesi, quindi è strettamente una questione di preferenze e le persone oggi potrebbero scegliere quello stile per gli stessi motivi che alcuni programmatori della vecchia scuola sceglievano prima (o forse i nuovi programmatori stanno solo guardando il loro codice e lo imitano). – stinky472

+0

Un altro possibile fattore influente relativo alla seconda ipotesi relativa ad altri linguaggi potrebbe essere il linguaggio funzionale come il lisp oi suoi successori. In lisp, tutto segue un formato rigoroso in cui tutto è scritto tra parentesi. Questo tipo di uniformità ha avuto un grande fascino per alcuni ed è stato odiato da altri, ma coloro che sono piaciuti potrebbero aver adattato il loro stile per ottenere un maggiore senso di uniformità visiva nel loro codice durante la migrazione a C. – stinky472

0

Un motivo posso vedere per questo:

return (ERROR_SUCCESS); 

è che è esprimere il concetto che ERROR_SUCCESS è opaco. Sappiamo tutti che è 0L, ma non dovremmo avere a.

Questa è una ragione abbastanza debole.

Un altro è che è esteticamente gradevole utilizzare le parentesi per coerenza, un'altra ragione debole.

Quindi, in altre parole, non lo uso da solo, ma non lo capovolgo se qualcun altro lo ha fatto. :)

+0

In che modo "esprime il concetto che 'ERROR_SUCCESS' è opaco? Cosa dovrebbe significare? Ma qualsiasi cosa sia, le parentesi non fanno proprio nulla per cambiarlo. –

1

Solo la mia sciocca speculazione:

#define RETURN(val) { if (val) printf("Main Exit With Error %d\n", val); return val; } 

int main(argc, argv) 
{ 
    ... 
    RETURN (E_FILENOTFOUND); 
} 
+0

La domanda riguardava' return', non 'RETURN'. .. Qualcuno che cercasse di adottare uno stile unificato che avrebbe funzionato sia con la parola chiave reale sia con una macro sostituzione - che avrebbe vagamente giustificato le parentesi altrimenti inutili - avrebbe usato il caso corretto. Se si utilizzano casi diversi, sicuramente potrebbero ricordarsi di usarli le parentesi se necessario –

2

C'è un motivo stupido - per fare ritorno più simile a una chiamata di funzione.

C'è un motivo più intelligente: se il codice viene generato, i generatori di codice spesso "giocano sul sicuro" mettendo parentesi attorno alle espressioni solo così non devono mai preoccuparsi della precedenza che si perde.

7

Questo è in realtà un requisito per lo stile del file di origine del kernel BSD.

man 9 style dice:

spazio dopo le parole chiave (se, mentre, per, ritorno, switch).

e

Valori in dichiarazioni di ritorno dovrebbero essere racchiusi tra parentesi.

+0

Molto interessante Grazie – Kolyunya

+0

Citando un vestito che usa l'idioma non risponde alla domanda se raggiunge qualcosa, ma non lo fa. Il loro stile guida anche il fastidio nel tentativo di giustificarlo? –

5

Le cose cambiano con l'uso di decltype(auto) in C++ 14 per dedurre il tipo di reso. Se vengono utilizzate parentesi, il tipo restituito viene considerato come riferimento:

decltype(auto) foo1() { 
    int n; 
    return (n); // parentheses causes return type to be int& 
} 

decltype(auto) foo2() { 
    int n; 
    return n; // no parentheses causes return type to be int 
} 

template<typename T> struct TD; 

int main() 
{ 
    // main.cpp:19:22: error: aggregate 'TD<int&()> f1' has incomplete type and cannot be defined TD<decltype(foo1)> f1; 
    TD<decltype(foo1)> f1; 

    // main.cpp:20:22: error: aggregate 'TD<int()> f2' has incomplete type and cannot be defined TD<decltype(foo2)> f2; 
    TD<decltype(foo2)> f2; 
}