Motivo per posizionare il tipo di funzione e il nome del metodo su diverse righe in C


16

Ho appena iniziato in una società e uno dei commenti di stile alla mia prima recensione del codice era che il tipo di ritorno e il nome del metodo dovrebbero essere su linee diverse. Ad esempio, questo

void foo() {
}

dovrebbe essere questo

void
foo() {
}

Ho sempre usato il primo stile e mi chiedevo se ci fosse un motivo diverso dalle preferenze personali per cui le persone usano il secondo stile? Non credo che il primo danneggi affatto la leggibilità. Uno è più comune dell'altro con programmatori C e grandi progetti open source?


3
Questo è nello standard GNU (non necessariamente dicendo che è una buona cosa, lo stile di rinforzo è strano). gnu.org/prep/standards/standards.html#Formatting
Gauthier

Risposte:


19

mi chiedevo se ci fosse qualche ragione diversa dalla preferenza personale per cui le persone usano il secondo stile?

Questo è uno stile che era popolare ai primi tempi di C, quindi la ragione potrebbe essere che è così che lo hanno fatto per molto tempo, hanno un sacco di codice simile a quello, ed è quello che tutti sono abituati. Non tanta preferenza personale quanto lo slancio aziendale.

Un altro motivo è che i nomi delle funzioni iniziano sempre nella prima colonna. I tipi di restituzione possono variare in lunghezza e possono essere alquanto complessi: posizionarli sulla propria riga semplifica la ricerca del nome della funzione.

Se la società ha uno stile prestabilito, potrebbe anche avere un documento sugli standard di codifica. Chiedi. Potrebbe spiegare i motivi di questa scelta e avere una copia ti aiuterà a evitare problemi simili nelle recensioni future.


2
Immagino sia anche collegato al limite di 80 caratteri ancora usato e difeso da molti programmatori. Se vuoi avere un limite di 80 caratteri e vuoi usare nomi descrittivi di metodi / funzioni, devi scendere a compromessi. La divisione dell'intestazione del metodo è una di queste.
Sulthan,

La dichiarazione può anche essere più lunga - pensa a diversi modificatori (non standard), come chiamare identificatori di convenzione (chiamata std, ecc.), Informazioni sulla visibilità dei simboli (DLLEXPORT) o __attributes. E poi, anche guardando al C ++ puoi avere tipi di ritorno relativamente complessi, quindi da qualche parte potresti dover aggiungere un'interruzione di riga.
johannes,

@Sulthan Non sono solo i programmatori (che sono abituati a terminare le finestre e utilizzano gli editor di terminali), interessante. Nella composizione, 72-80 caratteri è generalmente considerata la larghezza ideale per una colonna di testo in termini di leggibilità. (Ecco perché TeX e i suoi derivati ​​sono inadempienti rispetto a ciò che alcune persone considerano stranamente strette colonne.)
JAB

1
@JAB In realtà adesso. So anche che leggere un testo giustificato e leggere il codice sorgente sono due cose molto diverse e non hanno quasi nulla in comune, quindi la larghezza ideale è irrilevante.
Sulthan,

1
"Un altro motivo è che i nomi delle funzioni iniziano sempre nella prima colonna [e quindi sono] più facili da trovare." E questo è molto più di un semplice vantaggio visivo: ora possiamo cercare la regex ^start_of_a_long_funce essere portati immediatamente alla funzione che stiamo cercando.
underscore_d,

7

Questa è praticamente l'unica regola di formattazione del codice che ho trovato in realtà ha un impatto notevole sulla leggibilità e non richiede quasi sforzo (supponendo che il tuo editor di codice non inizi a litigare con te su di esso).

È buona norma progettare un linguaggio di programmazione per far apparire i nomi in una posizione coerente nelle dichiarazioni / definizioni. La logica è semplice: hai una bella ancora visiva (una parentesi graffa o solo una rientranza sospesa) che puoi usare per trovare immediatamente l'inizio del nome. Non è necessario analizzare effettivamente la lingua durante la scansione di un file per trovare il nome.

È lo stesso di quando stai formattando un documento: quando inizi una nuova sezione metti il ​​nome in grassetto - spesso sulla sua stessa linea - non sepolto da qualche parte, indifferenziato, in una lunga frase.

I primi C avevano firme molto concise: i tipi di restituzione erano facoltativi e i tipi di argomento venivano dichiarati dopo la firma. Anche i nomi tendevano ad essere molto brevi. Ciò ha mitigato l'impatto di un tipo di ritorno occasionale che compensa il nome.

double dot(x, y);

È ancora abbastanza digeribile.

Il C ++ ha peggiorato le cose. Ha spostato le specifiche del tipo di argomento in firme allungando le firme. Questa sintassi è stata successivamente adottata durante la standardizzazione di C.

static struct origin *find_origin(struct scoreboard *sb,
                  struct commit *parent,
                  struct origin *origin)

è meno digeribile, ma non troppo male. (Estratto da Git)

Ora considera le moderne pratiche di programmazione con nomi lunghi e descrittivi e tipi parametrizzati e vedi come questa scelta è diventata disastrosa. Un esempio da un'intestazione Boost:

template <class A1, class A2, class A3, class A4, class A5, class A6>
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&)
{ 
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
   return result_type(); 
}

Se stai scrivendo un codice generico, firme del genere non sono nemmeno fuori dal comune. Puoi trovare esempi di casi molto peggiori di questo senza provarci troppo.

C, C ++ e i loro derivati, Java e C #, sembrano essere le eccezioni ad avere dichiarazioni / definizioni leggibili. I loro predecessori e colleghi popolari (Fortran, ALGOL, Pascal) hanno posto i nomi prima dei tipi di risultati e, per fortuna, molti dei loro successori (Go, Scala, TypeScript e Swift per citarne alcuni) hanno scelto anche sintassi più leggibili.


1
Sii grato di non dover scrivere programmi Fortran. Te lo dico, dichiarare separatamente gli argomenti della tua funzione ti innervosiranno abbastanza rapidamente una volta che sarai costretto a farlo. Soprattutto quando si cerca di leggere la firma di una funzione per capire quali argomenti si aspetta: C ++ mette i tipi esattamente al loro posto, Fortran ti costringe ad avviare una ricerca per parole chiave visiva per il nome della variabile per determinarne il tipo.
cmaster - ripristina monica il

2
Inserire i tipi nella dichiarazione di funzione è stato davvero inventato dal C ++? Non avevo mai sentito parlare di questo, e sto lottando per trovare citazioni.
underscore_d

1
Vedere Lo sviluppo del linguaggio C . Nella sezione Standardizzazione, Ritchie menziona che la sintassi è stata presa in prestito dal C ++.
user2313838

5

Ho incontrato questo stile per la prima volta come nel 19 ° anno di lavoro con C & C ++. Era piuttosto sconcertato da come qualcuno potesse inventare questa cosa malvagia.

L'unico punto (potenzialmente) positivo che ho trovato è che puoi trovare la definizione di funciton usando grep ^ FuncName. Potrebbe essere rilevante fattore decennio + fa in alcune comunità di odio di strumenti reali ... Nel luogo in cui ho visto che era applicato al C ++ e alle funzioni dei membri della classe, che uccidono anche questo attributo.

Indovina la mia opinione. :)


1
grep -P '^(\w+::)?FuncName'
Kyle Strand,

Sì, i tipi di classe nei nomi delle funzioni non ostacolano affatto l'uso di questo. Quindi, è ancora utile per navigare rapidamente nei file sorgente. Per quanto riguarda l'aspetto malvagio o altro, le opinioni sono opinioni: sono arrivato a pensare che abbia un aspetto migliore.
underscore_d,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.