31 votes

Les éléments les plus importants d'une norme de codage C++ légère

J'ai participé à l'élaboration de normes de codage assez élaborées. D'après ma propre expérience, il est difficile de les faire respecter si l'on ne dispose pas de processus appropriés pour les maintenir et de stratégies pour les faire respecter.

Aujourd'hui, je travaille et je dirige un environnement où il est encore moins probable que des processus et des stratégies de suivi soient mis en place depuis longtemps. Je veux néanmoins maintenir un niveau minimum de code respectable. J'ai donc pensé que je pourrais obtenir de bonnes suggestions ici, et que nous pourrions ensemble produire un sous-ensemble raisonnable et léger des pratiques standard de codage les plus importantes pour que d'autres puissent l'utiliser comme référence.

Donc, pour souligner l'essentiel ici :

Quels éléments d'une norme de codage C++ sont les plus importants à respecter ?

  • Règles de réponse/vote

    • 1 candidat par réponse, de préférence avec un bref motivation.

    • Vote négatif candidats qui se concentrent sur le style et les directives de formatage subjectives. Il ne s'agit pas d'indiquer qu'elles sont sans importance, mais seulement qu'elles sont moins pertinentes dans ce contexte.

    • Vote négatif les candidats se concentrant sur la manière de commenter/documenter le code. Il s'agit d'un sujet plus vaste qui pourrait même mériter son propre billet.

    • Votez pour des candidats qui facilitent clairement un code plus sûr, qui minimise le risque de bogues énigmatiques, qui augmente la maintenabilité, etc.

    • Ne votez pas dans n'importe quelle direction sur les candidats dont vous avez des doutes. Même s'ils semblent raisonnables et intelligents, ou au contraire "quelque chose que personne n'utiliserait", votre vote doit être basé sur une compréhension claire et une expérience.

0 votes

Il est probable que vous créiez ici une collection de règles incohérentes, dont la plupart ne résoudront pas les problèmes résultant d'un comportement indéfini.

1 votes

Une autre approche consiste à prendre une norme de codage existante (par exemple AV JSF, MISRA C++, www.codingstandard.com) et à afficher les règles qui vous semblent être de bons candidats.

0 votes

Comment le style peut valoir un vote négatif. Vous demandez les meilleures pratiques dans les normes, puis vous insistez pour ignorer les meilleures. Un code où chacun choisit sa propre convention de nommage (par exemple) est le moins lisible possible. Votez comme vous voulez, mes frères !

0voto

gbjbaanb Points 31045

Les meilleures normes sont celles qui sont de petite taille et qui se concentrent sur ce qui importe vraiment pour créer un code de qualité. Elles n'essaient pas d'enseigner le codage, ni d'imposer une façon particulière de coder. Elles s'en tiennent généralement aux caractéristiques de cohérence et aux revues subjectives (par exemple, si le reste de votre équipe pense qu'un morceau de code est lisible, qu'il respecte les règles de cohérence et qu'il est commenté, alors ce sera toujours du bon code).

Donc, pour insister à nouveau : cohérence - convention de nommage, gestion de l'espace blanc, blocs de commentaires, structure des répertoires. Rien d'autre realmente questions

Edit pour Dustin : le gros problème avec les normes vient des exceptions. Si vous avez une norme qui dit "1 déclaration par ligne", vous ne pouvez pas écrire l'exemple inventé suivant :

SetColText(1,"col1"); SetColWidth(1, 10);
SetColText(2,"col1"); SetColWidth(2, 10);
...
SetColText(9,"col1"); SetColWidth(9, 10);

Mais je dirais que c'est plus lisible, et donc moins sujet à erreur que de les séparer. (Je suis sûr que vous pouvez trouver de meilleurs exemples).

C'est ce que je veux dire : dire aux gens comment écrire du code et comment le formater selon des règles strictes finira toujours par échouer d'une manière et à des endroits que vous n'aviez pas prévus. Il est donc de loin préférable de faire confiance à vos codeurs pour qu'ils le fassent correctement après avoir imposé quelques règles. S'ils ont quelques règles à suivre, ils écriront un bon code, discipliné, de sorte que vous n'aurez pas besoin du reste des règles pourries.

Vous voyez certaines normes qui s'étendent sur des pages et des pages. (Celle de Philips sur le C# fait 48 putains de pages !).

Donc, étant donné que vous avez une équipe de codeurs de qualité, que devez-vous faire pour faciliter le travail avec leur code ? La réponse est toujours la cohérence de "l'endroit" où ils mettent le code, pas comment ils l'écrivent. par exemple, vous avez toujours un répertoire bin, et obj dans votre projet est un bon standard. Vous pouvez prendre n'importe quel projet et savoir où se trouvent les choses contrairement à quelqu'un qui construit tous ses binaires dans son répertoire c:/mybin parce que c'est plus facile pour lui.

0voto

paercebal Points 38526

Limitez les types que vous utilisez

Si vous devez utiliser un type entier, choisissez-en un et conservez-le. Vous éviterez ainsi les problèmes liés au mélange des types short, int, long, etc.

// BAD
int i ;
long j ;
short k ;

// GOOD (if you choose the "int" as integer)
int i ;
int j ;
int k ;

Il en va de même pour les types réels : Choisissez-en un (par exemple, double), et n'en utilisez pas d'autre.

Etc.

Note : Il y a toujours le problème des signés/non signés, qui ne peut pas toujours être évité, et le fait que STL utilise ses propres types d'entiers (i.e. std::vector::size_type), mais tout le code restant ne devrait pas se mélanger.

Note 2 : Vous pourriez utiliser typedef pour "choisir" votre type préféré pour les nombres entiers et réels signés. Cela permettrait un changement peu coûteux si nécessaire.

Comment cela facilite clairement un code plus sûr, qui minimise le risque de bogues énigmatiques, qui augmente la maintenabilité, etc ?

Certains bogues sont créés en comparant des types non signés à des types signés, ce qui entraîne une mystérieuse perte de précision ou un dépassement de capacité des entiers.

Les compilateurs envoient généralement des avertissements au moment de la compilation, mais la réponse habituelle consiste alors à "couler" l'avertissement, ce qui peut contribuer à masquer l'erreur.

Editar

plinth a fait un commentaire utile que je vais copier-coller ici :

Ayant écrit beaucoup de code qui doit interagir avec des choses au niveau du matériel, je ne peux pas dire grand chose de cette directive. Pour ce niveau de travail, je préfère que les types intégraux soient abstraits avec des noms qui incluent la précision (par exemple, int16, uint16, int32, uint32, etc.) - plinth Aug 18 at 20:50

plinth a raison, bien sûr. Parfois, vous devez traiter avec int16, uint8 et d'autres types "précisément définis".

Cela n'invalide pas le message ci-dessus, mais le complète.

La source du bogue est le mélange de différents types (conversion de unsigned char en int, par exemple), il faut donc éviter ce genre de mélange. Les règles suivantes s'appliquent donc :

  • Choisissez un type intégral générique (par exemple int), et tenez-vous en à ce type lorsque vous traitez des entiers génériques (on peut dire la même chose des réels).
  • Si (et seulement si) vous avez besoin de types exacts (comme uint8 ou int16), utilisez-les.
  • Ne mélangez jamais différents types.
  • Si vous realmente doit mélanger différents types, alors soyez très très prudent.

Voici un exemple de code qui serait cassé :

void * doAllocate(uint32 i)
{
   // try to allocate an array of "i" integers and returns it
}

void doSomething()
{
   uint32 i0 = 225 ;
   int8   i1 = 225 ;  // Oops...

   doAllocate(i0) ;   // This will try to allocate 255 integers
   doAllocate(i1) ;   // This will TRY TO allocate 4294967265
                      // integers, NOT 225
}

0voto

jussij Points 7391

Assurez-vous que les destructeurs sont définis comme virtuel :

 class GoodClass {
 public:
   GoodClass();
   virtual ~GoodClass()
 };

 class BadClass {
 public:
   BadClass();
   ~BadClass()
 };

-2voto

kenny Points 9150

Pas d'onglets (permet une meilleure utilisation des outils externes/autres) et un espace fixe inséré pour les onglets.

-7voto

Trier les fonctions dans les déclarations et définitions de classes par leur nom. Il est ainsi plus facile de les localiser dans le fichier .cpp. De plus, cela vous libère l'esprit car vous n'avez pas à vous demander où placer votre nouvelle fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X