URL: https://linuxfr.org/users/oliver_h/journaux/le-tiret-bas-underscore-au-debut-des-variables-membres Title: C✙✙ Le tiret bas (underscore) au début des variables membres ? Authors: Oliver Date: 2018年08月18日T18:17:31+02:00 License: CC By-SA Tags: c++, règle_de_nommage, variables, classe, norme et codage Score: 11 En réponse à [guppy](https://linuxfr.org/users/small_duck/journaux/tirez-vous-une-buche-qu-on-cause-c-et-singletons#comment-1746778), j’ai rédigé un [long commentaire](https://linuxfr.org/users/small_duck/journaux/tirez-vous-une-buche-qu-on-cause-c-et-singletons#comment-1746934) qui mérite d’être promu en journal. `\_o_/` # La norme C++ réserve l’utilisation du tiret bas *(underscore)* Résumé de la norme **C✙✙** : https://en.cppreference.com/w/cpp/language/identifiers> [...]>> An identifier can be used [to name](https://en.cppreference.com/w/cpp/language/declarations) objects, references, functions, enumerators, types, class members, namespaces, templates, template specializations, parameter packs, goto labels, and other entities, with the following exceptions:>> * the identifiers that are [keywords](https://en.cppreference.com/w/cpp/keyword) cannot be used for other purposes;> * the identifiers with a double underscore anywhere are reserved;> * the identifiers that begin with an underscore followed by an uppercase letter are reserved;> * the identifiers that begin with an underscore are reserved in the global namespace.>> [...] # Reformulons + exemples On reformule différemment : 1. Éviter le tiret bas au début ; ```cpp #ifndef _MA_CLASSE_H // Non, on a dit pas au début #define _MA_CLASSE_H ... #endif #ifndef MA_CLASSE_H_ // Oui, autorisé à la fin #define MA_CLASSE_H_ ... #endif ``` 2. Éviter deux tirets bas consécutifs n’importe où ; ```cpp #ifndef MA_CLASSE__H // Non, pas de double tiret bas au milieu #define MA_CLASSE__H ... #endif #ifndef MA_CLASSE_H__ // Non, pas à la fin non plus #define MA_CLASSE_H__ ... #endif ``` 3. Exception du tiret bas au début. Autorisé dans une portée locale *(local scope)* et suivi par une minuscule (ou un chiffre...). ```cpp #ifndef MA_CLASSE_H // Oui #define MA_CLASSE_H class _MaClasse // Non { const double _PI = 3.14; // Non int _MonEntier = 0; // Non int _monEntier = 0; // Oui int __monEntier = 0; // Non int _mon_entier = 0; // Oui int _mon__entier = 0; // Non int _0_0_ = 0; // Oui int _ = 0; // Oui int _Fonction(); // Non int _fonction(); // Oui }; int _fonction(); // Non int fonction (int _a) { // Oui int _ = _a; // Oui return _; } #endif ``` # Règle simple On simplifie la règle pour la retenir : 1. Jamais deux tirets bas consécutifs n’importe où ; 2. Le tiret bas au début réservé aux `_variablesMembres`. Car le tiret bas pour les variables membres à des avantages. Mais ceux qui ne sont pas d’accord pourraient plutôt adopter cette règle : 1. Jamais deux tirets bas consécutifs ; 2. Jamais le tiret bas au début. # Avantages du tiret bas au début 1. Quand seules les variables commencent par un tiret bas, l’auto-complétion distingue les fonctions des variables. Lors de l’activation de l’auto-complétion, tout est listé, mais d’abord les fonctions sans être pollué par les variables. Et si on cherche le nom d’une variable, il suffit d’entrer un tiret bas. Attention à éviter les variables membres avec une majuscule en second caractère car c’est potentiellement un mot réservé. 2. Un second avantage, plus esthétique, est l’alignement des tiret bas lors de la déclaration des variables membres. C’est difficilement le cas avec le tiret bas final. Exemples issus des [GreatPractices C++ rules](https://github.com/olibre/GreatPractices/blob/master/cpp/rules.md#nstr--struct-data-member-in-camelcase---) : ```cpp struct Limit { int32_t quantity; double price; bool isActive; }; class MyClass { public: double volume() const; private: int32_t _quantity; double _price; bool _isActive; }; double MyClass::volume() const { volume = _price * _quantity return volume; } ``` # Quand utiliser le tiret du bas ? Si une `struct` (ou une `class`) expose ses variables en `public` et ne possède pas (ou peu) de fonctions, alors pas besoin de distinguer les variables des fonctions (pas d’intérêt à utiliser les tirets du bas). Par contre, si une `class` (ou une `struct`) expose des fonctions en `public` et le reste est `private`, alors distinguer les nombreuses fonctions des nombreuses variables est intéressant (variables membres préfixées par le tiret du bas pour les variables s’applique). Bien entendu, une `class` ou `struct` qui a pour destinée de ne posséder que peu de fonctions et variables, alors pas besoin d’artifice pour distinguer les fonctions des variables, le tiret du bas n’est pas obligatoire. ## Règle simple : 1. Choisir `struct` quand ce sont essentiellement des variables `public`, et donc ne pas utiliser le tiret du bas ; 2. Dans les autres cas, choisir plutôt `class` et préfixer les variables membres avec un tiret bas ; 3. Déroger à la règle dans les autres cas ([trait](https://fr.wikipedia.org/wiki/Trait_(programmation)), ...). # Voir aussi * [*Why use prefixes on member variables in C++ classes?*](https://stackoverflow.com/questions/1228161) * [*Convention of using underscores in C++ class member names*](https://stackoverflow.com/questions/6825186/convention-of-using-underscores-in-c-class-member-names) * [*Class members prefixed with underscore*](https://stackoverflow.com/questions/7979797) * [*Might starting variables/members with an underscore puzzle the compiler?*](https://programmers.stackexchange.com/questions/191828) * [*Why C# and C++ use `_name` convention?*](https://stackoverflow.com/questions/3823913) * [*What kind of prefix do you use for member variables?*](https://stackoverflow.com/questions/111605)