1056 votes

Quelles sont les règles sur l’utilisation d’un trait de soulignement dans un identificateur C++ ?

Il est fréquent en C++ pour n’en nommer membre variables avec une sorte de préfixe pour désigner le fait qu’ils sont des variables de membre, plutôt que des variables locales ou des paramètres. Si vous venez d’un milieu MFC, vous utiliserez probablement « m_foo ». J’ai aussi vu « myFoo » occasionnellement.

C# (ou peut-être juste .NET) semble vous recommandons d’utiliser seulement un trait de soulignement, comme dans « _foo ». Si cela est permis par la norme C++ ?

954voto

Loki Astari Points 116129

Les règles (ce qui ne change pas en C++11):

  • Réservés dans tous les contextes, y compris pour une utilisation comme la mise en œuvre des macros:
    • les identificateurs commençant par un trait de soulignement et une lettre majuscule
    • les identificateurs adjacentes contenant des caractères de soulignement (ou "double underscore")
  • Réservée dans l'espace de noms global:
    • les identificateurs commençant par un trait de soulignement
  • Aussi, tout dans l' std d'espace de noms est réservé. (Vous êtes autorisé à ajouter des spécialisations de modèle, cependant).

À partir de 2003 de la Norme C++:

17.4.3.2.1 noms Globaux [lib.mondiale.noms]

Certains ensembles de noms et de signatures de fonction sont toujours réservés à la mise en œuvre:

  • Chaque nom qui contient un double trait de soulignement (_ _) ou commence par un caractère de soulignement suivi par une lettre majuscule (2.11) est réservée à la mise en œuvre de toute utilisation.
  • Chaque nom qui commence par un caractère de soulignement est réservé à la mise en œuvre de l'utiliser comme un nom dans l'espace de noms global.165

165) Ces noms sont également réservés à l'espace de noms ::std (17.4.3.1).

Parce que le C++ est basé sur la norme C (1.1/2, C++03) et C99 est une référence normative (1.2/1, C++03) ces procédures s'appliquent également, à partir de 1999 C Standard:

7.1.3 identificateurs Réservés

Chaque en-tête déclare ou définit l'ensemble des identifiants dans la subdivision, et éventuellement déclare ou définit identifiants dans son futur associé de la bibliothèque des directions de la subdivision et les identificateurs qui sont toujours réservées pour toute utilisation ou pour utiliser comme fichier de la portée des identificateurs.

  • Tous les identificateurs commençant par un trait de soulignement et une lettre majuscule ou un autre trait de soulignement sont toujours réservés pour toute utilisation.
  • Tous les identificateurs commençant par un caractère de soulignement sont toujours réservés pour une utilisation en tant qu'identifiants avec le fichier de la portée à la fois l'ordinaire et le nom de la balise espaces.
  • Chaque nom de la macro dans l'une des subdivisions (y compris la future bibliothèque les directions) est réservé pour une utilisation comme spécifié si l'un de ses associés en-têtes; sauf mention explicite contraire (voir 7.1.4).
  • Tous les identificateurs de liaison externe dans l'une des subdivisions (y compris les avenir de la bibliothèque directions) sont toujours réservés pour une utilisation en tant qu'identifiants externes de liaison.154
  • Chaque identifiant à la portée de fichier répertoriés dans l'une des subdivisions (y compris les avenir de la bibliothèque de sens) est réservé pour une utilisation en tant que nom de la macro et comme un identificateur avec la portée du fichier dans le même espace de nom si l'un de ses associés en-têtes est inclus.

Pas d'autres identifiants sont réservés. Si le programme déclare ou définit un identificateur dans un contexte dans lequel il est réservé (autres que celles autorisées par 7.1.4), ou de définir une réservés identificateur de nom de la macro, le comportement est indéfini.

Si le programme supprime (avec #undef) toute définition de macro d'un identifiant dans la première groupe énumérés ci-dessus, le comportement est indéfini.

154) La liste des identificateurs réservés avec une liaison externe inclut errno, math_errhandling, setjmp, et va_end.

Des classes supplémentaires de l'identificateur de noms sont réservés pour de futures extensions du langage C ou POSIX.1 l'environnement. Si l'utilisation de ces noms pour vos besoins propres, à droite maintenant ne pourrait pas causer un problème, ils soulèvent la possibilité d'un conflit avec les futures versions de la C ou POSIX normes, de sorte que vous devriez éviter ces noms.

  • Les noms commençant par un " E " suivi d'un chiffre ou une lettre majuscule:
    • peut être utilisé pour plus d'erreur des noms de code. Voir Les Rapports D'Erreurs.
  • Les noms qui commencent par " est " ou " de " suivie d'une lettre minuscule
    • peut être utilisé pour d'autres tests et des fonctions de conversion.
  • Les noms qui commencent par 'LC_" suivi d'une lettre majuscule
    • peut être utilisé pour d'autres macros définition des paramètres régionaux attributs.
  • Les noms de toutes les fonctions mathématiques suffixé par " f " ou " l " sont réservés
    • pour les fonctions qui opèrent sur des float et long double arguments, respectivement.
  • Les noms qui commencent par 'SIG', suivie par une lettre majuscule sont réservés
    • pour plus d'un nom de signal.
  • Les noms qui commencent par 'SIG_" suivi d'une lettre majuscule sont réservés
    • pour plus de signal actions.
  • Les noms commençant par 'str', 'mem', ou " wcs " suivi d'une lettre minuscule sont réservés
    • pour plus de chaîne et les fonctions de tableau.
  • Les noms commençant par " PRI " ou "SCN", suivi par une lettre minuscule ou 'X' sont réservés
    • pour plus d'spécificateur de format macros
  • Les noms qui se terminent par '_t' sont réservés
    • pour d'autres types de noms.

Personnellement, je n'ai juste pas commencer identifiants avec des traits de soulignement. Nouvel ajout à ma règle: Ne pas utiliser de doubles traits de soulignement n'importe où, ce qui est facile car j'utilise rarement le trait de soulignement.

Après avoir fait des recherches sur cet article je n'ai plus la fin de mes identifiants avec '_t' comme il est réservé par la norme POSIX.

La primauté sur tout autre identifiant qui se termine par "_t' m'a surpris beaucoup. Je pense que c'est une norme POSIX (pas encore sûr) à la recherche de précisions et officiel le chapitre et le verset. C'est à partir de la GNU libtool manuel, liste des noms réservés.

CesarB fourni le lien ci-après pour la POSIX 2004 réservés symboles et notes "que beaucoup d'autres réservés les préfixes et les suffixes ... peut être trouvé là-bas". L' POSIX 2008 réservés symboles sont définis ici. Les restrictions sont un peu plus nuancées que celles ci-dessus.

222voto

paercebal Points 38526

Les règles pour éviter les collisions de noms sont à la fois dans la norme C++ (voir le livre de Stroustrup) et mentionné par le C++ gourous (Sutter, etc.).

Règle personnelle

Parce que je ne veux pas avoir affaire à des cas, et je voulais une règle simple, j'ai conçu un personnel qui est à la fois simple et correcte:

Lorsque vous nommez un symbole, vous évitez les collisions avec le compilateur/OS/bibliothèques standard si vous:

  • ne jamais démarrer un symbole avec un trait de soulignement
  • jamais le nom d'un symbole avec deux années consécutives souligne à l'intérieur.

Bien sûr, de mettre votre code dans un espace de noms unique aide à éviter les collisions, trop (mais ne protège pas contre le mal de macros)

Quelques exemples

(J'utilise des macros, car ils sont le code plus polluantes de C/C++ symboles, mais il pourrait être quelque chose de la variable nom de la classe nom)

#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT

Des extraits de C++0x projet

À partir de la n3242.pdf fichier (j'attend le dernier standard de texte similaire):

17.6.3.3.2 noms Globaux [global.noms]

Certains ensembles de noms et de signatures de fonction sont toujours réservés à la mise en œuvre:

- Chaque nom qui contient un double trait de soulignement _ _ ou commence par un caractère de soulignement suivi par une lettre majuscule (2.12) est réservée à la mise en œuvre de toute utilisation.

- Chaque nom qui commence par un caractère de soulignement est réservé à la mise en œuvre de l'utiliser comme un nom dans l'espace de noms global.

Mais aussi:

17.6.3.3.5 définis par l'Utilisateur littérale suffixes [usrlit.suffixe]

Suffixe littéral identificateurs qui ne commence pas par un caractère de soulignement sont réservés pour l'avenir de la normalisation.

Cette dernière clause est source de confusion, sauf si vous considérez qu'un nom commençant par un trait de soulignement et suivie d'une lettre minuscule serait Ok si pas définie dans l'espace de noms global...

50voto

Roger Lipscombe Points 34344

À partir de MSDN:

L'utilisation de deux séquentielle des caractères de soulignement ( __ ) au début d'un identifiant, ou un seul trait de soulignement suivi d'une lettre majuscule, est réservé pour le C++ mises en œuvre dans tous les domaines. Vous devez éviter d'utiliser un trait de soulignement suivie d'une lettre minuscule pour les noms de fichier champ d'application en raison de la possibilité de conflits actuels ou futurs réservés identifiants.

Cela signifie que vous pouvez utiliser un seul trait de soulignement comme une variable de membre préfixe, aussi longtemps qu'il est suivi par une lettre minuscule.

C'est apparemment issus de la section 17.4.3.1.2 de la norme C++, mais je ne trouve pas la source d'origine de la norme complète en ligne.

Voir également cette question.

29voto

Max Lybbert Points 11822

En ce qui concerne l’autre partie de la question, il est courant de mettre le trait de soulignement à la fin du nom de la variable à ne pas entrer en conflit avec quoi que ce soit interne.

J’ai cela même à l’intérieur des classes et espaces de noms, parce que j’ai ensuite seulement se rappeler une règle (par rapport à « à la fin du nom dans la portée globale et le début du nom partout ailleurs).

2voto

John Millikin Points 86775

Oui, les traits de soulignement peuvent être utilisés n’importe où dans un identificateur. Je crois que les règles sont : tout d’a à z, A-Z, _ dans le premier caractère et ceux + 0-9 pour les caractères suivants.

Trait de soulignement préfixes sont communs dans le code C--un trait de soulignement simple signifie « privé », et double trait de soulignement est habituellement réservés pour une utilisation par le compilateur.

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