• [^] # Règle des tirets bas (underscores)

    Posté par (site web personnel) . En réponse au journal Tirez-vous une bûche, qu'on cause C++ et singletons. Évalué à 3. Dernière modification le 18 août 2018 à 16:55.

    C’est l’occasion de rappeler les règles du tiret bas (underscore) dans le nommage \_o_/

    La nomre C++

    Le résumé de la norme C++ : https://en.cppreference.com/w/cpp/language/identifiers

    [...]

    In declarations

    An identifier can be used to name 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 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 ;

      #ifndef _MA_CLASSE_H # Non car commence par "_M »
      #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ù ;

      #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...).

      #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.

    Avantage à nommer ses variables membres avec un tiret bas au début

    Je cite les GreatPractices C++ rules

    N. CLS Class data member in _camelCase

    • Same rule as for struct member but prefixed with an underscore "_"
    • This rule may not be applied:
    • when the class contains few functions and data members
    • for special members as static variables

    Rationale:

    • By convention struct has public data and provides few functions
    • In contrast, class has private data and often provides many functions
    • This rule avoids messing the Auto-Completion on class between data (private) and functions (public)
    • This rule allows Auto-Completion to separate data/functions (arranged in alphabetical order)
    • Developer knows if he/she wants to see the list of data members or the list of functions
    • No problem to start with "_" + lowercase inside a class scope (reserved only in global scope)
    • But starting with "_" + UPPERCASE or double "__" is reserved in any scope
    class MyClass
    {
    public:
     double getTradingVolume() const;
    private:
     int32_t _quantity;
     double _price;
     bool _isActive;
    };
    double MyClass::getTradingVolume() const
    {
     return _price * _quantity;
    }

    See also related questions:

    Dans la langue de Molière

    Constats :

    • En général, les struct fournissent des variables public et pas (peu) de fonctions ;
    • En général, les class fournissent des fonctions public (le reste est private) ;
    • Donc, dans une struct, pas besoin de distinguer les variables des fonctions ;
    • Par contre, dans une class ce serait pratique de les distinguer.

    Avantages de commencer par un tiret bas :

    • La déclaration des variables membres est alignée (c’est plus joli que les tiret bas à la fin) ;
    • L’auto-complétion tire bénéfice car on sélectionne les variables ou les fonctions selon si on commence à taper un tiret bas ou pas.

    Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)