Raison du placement du type de fonction et du nom de méthode sur différentes lignes en C

16

Je viens de commencer dans une entreprise et l'un des commentaires de style lors de ma première revue de code était que le type de retour et le nom de la méthode devaient être sur des lignes différentes. Par exemple, cette

void foo() {
}

devrait être ceci

void
foo() {
}

J'ai toujours utilisé le premier style, et je me demandais s'il y avait une raison autre que la préférence personnelle pour laquelle les gens utilisent le deuxième style? Je ne pense pas que la première nuit à la lisibilité. L'un est-il plus courant que l'autre avec les programmeurs C et les grands projets open source?

gsingh2011
la source
3
C'est dans la norme GNU (ne disant pas nécessairement que c'est une bonne chose, le style de contreventement est étrange). gnu.org/prep/standards/standards.html#Formatting
Gauthier

Réponses:

19

se demandait s'il y avait une raison autre que la préférence personnelle pour laquelle les gens utilisent le deuxième style?

C'est un style qui était populaire au début de C, donc peut-être que c'est comme ça qu'ils l'ont fait pendant très longtemps, ils ont beaucoup de code qui ressemble à ça, et c'est ce que tout le monde est habitué. Pas tant une préférence personnelle qu'une dynamique d'entreprise.

Une autre raison est que les noms de fonction commencent toujours dans la première colonne. Les types de retour varient en longueur et peuvent être quelque peu complexes - mettre le type sur sa propre ligne facilite la recherche du nom de la fonction.

Si l'entreprise a un style défini, elle peut également disposer d'un document sur les normes de codage. Demande-le. Cela peut expliquer la ou les raisons de ce choix, et en avoir une copie vous aidera à éviter des problèmes similaires dans les futures revues.

Caleb
la source
2
Je suppose qu'il est également connecté à la limite de 80 caractères encore utilisée et défendue par de nombreux programmeurs. Si vous voulez avoir une limite de 80 caractères et que vous souhaitez utiliser des noms de méthode / fonction descriptifs, vous devez faire des compromis. Le fractionnement de l'en-tête de la méthode en fait partie.
Sulthan
La déclaration peut également être plus longue - pensez à différents modificateurs (non standard), comme l'appel des identificateurs de convention (stdcall, etc.), des informations sur la visibilité des symboles (DLLEXPORT) ou __attributes. Et puis, lorsque vous regardez également C ++, vous pouvez avoir des types de retour relativement complexes, donc quelque part, vous devrez peut-être ajouter un saut de ligne.
johannes
@Sulthan Ce n'est pas seulement les programmeurs (qui sont habitués aux fenêtres de terminaux et aux éditeurs de terminaux), ce qui est intéressant. En composition, 72 à 80 caractères sont généralement considérés comme la largeur idéale pour une colonne de texte en termes de lisibilité. (D'où la raison pour laquelle TeX et ses dérivés utilisent par défaut ce que certains considèrent comme des colonnes étrangement étroites.)
JAB
1
@JAB je l'ai maintenant. Je sais aussi que la lecture d'un texte justifié et la lecture du code source sont deux choses très différentes et n'ont presque rien en commun, donc la largeur idéale n'a pas d'importance.
Sulthan
1
"Une autre raison est que les noms de fonction commencent toujours dans la première colonne [et sont donc] plus faciles à trouver." Et c'est bien plus qu'un simple avantage visuel: nous pouvons maintenant rechercher l'expression rationnelle ^start_of_a_long_funcet accéder immédiatement à la fonction que nous recherchons.
underscore_d
7

C'est à peu près la seule règle de mise en forme de code que j'ai trouvée qui a en fait un impact notable sur la lisibilité et cela ne prend presque aucun effort (en supposant que votre éditeur de code ne commence pas à se battre avec vous à ce sujet).

Il est bon de concevoir un langage de programmation pour que les noms apparaissent dans une position cohérente dans les déclarations / définitions. La justification est simple: vous avez une belle ancre visuelle (une accolade bouclée ou juste une empreinte suspendue) que vous pouvez utiliser pour trouver immédiatement le début du nom. Vous n'avez pas besoin d'analyser réellement la langue lorsque vous parcourez un fichier pour trouver le nom.

C'est la même chose que lorsque vous formatez un document: lorsque vous commencez une nouvelle section, vous mettez le nom en gras - souvent sur sa propre ligne - non enterré quelque part, indifférencié, dans une longue phrase.

Les premiers C avaient des signatures très laconiques: les types de retour étaient facultatifs et les types d'arguments étaient déclarés après la signature. Les noms ont également tendance à être très courts. Cela a atténué l'impact d'avoir un type de retour occasionnel compensant le nom.

double dot(x, y);

Est encore assez digeste.

C ++ a rendu cela un peu pire. Il a déplacé les spécifications de type d'argument dans les signatures, ce qui rallonge les signatures. Cette syntaxe a ensuite été adoptée lors de la normalisation de C.

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

est moins digestible, mais pas trop mal. (Extrait de Git)

Considérez maintenant les pratiques de programmation modernes avec des noms longs et descriptifs et des types paramétrés et voyez comment ce choix est devenu désastreux. Un exemple d'un en-tête 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(); 
}

Si vous écrivez du code générique, de telles signatures ne sont même pas hors de l'ordinaire. Vous pouvez trouver des exemples de cas bien pires que cela sans trop essayer.

C, C ++ et leurs dérivés, Java et C #, semblent être les exceptions à la possibilité d'avoir des déclarations / définitions lisibles. Leurs prédécesseurs et pairs populaires (Fortran, ALGOL, Pascal) ont placé les noms avant les types de résultats et, heureusement, beaucoup de leurs successeurs (Go, Scala, TypeScript et Swift pour n'en nommer que quelques-uns) ont également choisi des syntaxes plus lisibles.

user2313838
la source
1
Soyez reconnaissant de ne pas avoir à écrire des programmes Fortran. Je vous le dis, déclarer séparément vos arguments de fonction vous mettra sur les nerfs assez rapidement une fois que vous serez obligé de le faire. Surtout lorsque vous essayez de lire une signature de fonction pour comprendre quels arguments elle attend: C ++ place les types là où ils appartiennent, Fortran vous oblige à lancer une recherche visuelle par mot clé du nom de la variable pour déterminer son type.
cmaster - réintègre monica
2
Est-ce que mettre les types dans la déclaration de fonction a vraiment été inventé par C ++? Je n'avais jamais entendu parler de cela, et j'ai du mal à trouver des citations.
underscore_d
1
Voir le développement de la langue C . Dans la section Standardisation, Ritchie mentionne que la syntaxe a été empruntée à C ++.
user2313838
5

J'ai rencontré ce style pour la 19e année en travaillant avec C & C ++. Était à peu près déconcerté sur la façon dont quelqu'un pouvait inventer cette mauvaise chose.

Le seul point (potentiellement) positif que j'ai pu trouver est que vous pouvez trouver la définition de fonction en utilisant grep ^ FuncName. Peut-être un facteur pertinent il y a une dizaine d'années dans certaines communautés de haine d'outils réels ... À l'endroit où j'ai vu, il était appliqué au C ++ et aux fonctions des membres de la classe, qui tuent même cet attribut.

Devinez mon avis. :)

Balog Pal
la source
1
grep -P '^(\w+::)?FuncName'
Kyle Strand
Oui, les types de classe dans les noms de fonction n'entravent pas du tout l'utilisation de ceci. Donc, c'est toujours une chose utile pour naviguer rapidement dans les fichiers source. En ce qui concerne le mal ou quoi que ce soit, les opinions sont des opinions: j'en suis venu à penser qu'il a l'air mieux.
underscore_d