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 !

68voto

Aardvark Points 4775

Préférez RAII .

Les pointeurs auto (et partagés dans boost et C++0x) de STL peuvent aider.

0 votes

Je dirais "préférer RAII" - je ne l'exigerais certainement pas dans une norme.

0 votes

Approuvé. Dans un endroit où je travaillais, les gens discutaient de symétries comme "perfer". Finalement, notre norme a été rédigée comme si tout était une exigence absolue (même s'il était possible de s'en écarter après une révision).

0 votes

Sans RAII, il est assez difficile d'écrire un code sûr et facile à maintenir.

58voto

xtofl Points 22333

Utilisez const par défaut. Ils offrent des garanties au lecteur/mainteneur, et sont beaucoup plus faciles à intégrer qu'à insérer après coup.

Les variables membres et les méthodes sont déclarées const ainsi que des arguments de fonction. const Les variables membres imposent une utilisation correcte de la liste d'initialisation.

Un effet secondaire de cette règle : éviter les méthodes avec des effets secondaires.

------ EDIT

const membre variables semblent être une bonne idée ; ce n'est pas toujours le cas : ils rendent effectivement cualquier objet immuable. Cela devient problématique pour, par exemple, trier un vecteur.

struct A {
    const int i;
};

bool operator<(const A& lhs, const A& rhs) {
    return lhs.i < rhs.i;
}

int main() {
    std::vector<A> as;
    as.emplace_back(A{1});
    std::sort(begin(as), end(as));
}

message d'erreur :

... note: copy assignment operator of 'A' is implicitly deleted because
field 'i' is of const-qualified type 'const int'
...
in instantiation of function template specialization 'std::sort<...>'
requested here

    std::sort(begin(as), end(as));

48voto

paercebal Points 38526

Utiliser les casts C++ au lieu des casts C

utiliser :

  • static_cast
  • const_cast
  • reinterpret_cast
  • dynamic_cast

mais jamais les casts de style C.

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

Chaque acteur a des pouvoirs limités. Par exemple, si vous voulez supprimer un const (pour une raison quelconque), const_cast ne changera pas le type en même temps (ce qui pourrait être un bug difficile à trouver).

Cela permet également à l'examinateur de les rechercher et au codeur de les justifier si nécessaire.

0 votes

De plus, un cast C est toujours traité comme un reinterpret_cast<> lorsqu'il s'agit de déclarations forward. Et les cast C sont incapables de downcast ou crosscast correctement.

1 votes

Oui, absolument, mais je ne sais pas si je recommanderais reinterpret_cast non plus...

0 votes

Cela entre en conflit avec la règle "utiliser le cast le plus faible possible", car reinterpret_cast est plus fort que le cast de style C et parfois vous n'avez rien entre lui et static_cast autre que le cast de style c. Par exemple, la conversion d'un pointeur vers un tampon d'octets en un struct{} (schéma d'analyse binaire régulier). Recommanderiez-vous un reinterpret_cast ? Je ne pense pas.

40voto

Aardvark Points 4775

Utilisez des références au lieu de pointeurs lorsque cela est possible. Cela évite les contrôles défensifs constants de NULL.

2 votes

Mais si vous déréférencez un pointeur pour initialiser la référence, assurez-vous d'abord que le pointeur n'est pas NULL !

0 votes

Oui - mais si vous utilisiez toujours des références, vous n'auriez pas ce pointeur pour commencer ! Je plaisante... J'ai été mordu par le même problème que vous soulevez à plusieurs reprises.

2 votes

+1 à l'effet, pas au raisonnement. je renvoie parfois un itérateur nul, par exemple find(). est-ce mauvais ? les langages de plus haut niveau qui utilisent des types de référence ont typiquement un None objet.

36voto

Ferruccio Points 51508

Assurez-vous que le niveau d'avertissement de votre compilateur est suffisamment élevé (/Wall de préférence) pour qu'il puisse repérer les erreurs stupides telles que :

if (p = 0)

alors que tu voulais vraiment

if (p == 0)

pour que tu n'aies pas besoin de recourir à des trucs encore plus stupides :

if (0 == p)

qui dégradent la lisibilité de votre code.

4 votes

... et compiler avec WISE (Warning is Error)

1 votes

D'une autre manière : Si p est const, alors if(p = 0) ne compilera pas de toute façon, mais ceci est un autre post...

0 votes

Pour la modération, voir stackoverflow.com/questions/237719 Je suis moi-même surpris et pas heureux de voir à quel point cela a touché les nerfs. Néanmoins, je pense que c'est une règle valable !

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