À quoi servent les noms de caractères universels dans les identificateurs en C ++

11

Le standard C ++ (je l'ai remarqué dans le nouveau, mais il existait déjà en C ++ 03) spécifie les noms de caractères universels, écrits en tant \uNNNNque \UNNNNNNNNet représentant les caractères avec des points de code unicode NNNN/ NNNNNNNN. Ceci est utile avec les littéraux de chaîne, d'autant plus que les littéraux de chaîne explicitement UTF-8, UTF-16 et UCS-4 sont également définis. Cependant, les littéraux de caractères universels sont également autorisés dans les identificateurs. Quelle est la motivation derrière cela?

La syntaxe est évidemment totalement illisible, les identificateurs peuvent être modifiés pour l'éditeur de liens et ce n'est pas comme s'il y avait une fonction standard pour récupérer les symboles par leur nom de toute façon. Alors, pourquoi quelqu'un utiliserait-il réellement un identifiant contenant des littéraux de caractère universel?

Edit: Puisqu'il existait déjà en C ++ 03, une question supplémentaire serait de savoir si vous avez réellement vu un code qui l'a utilisé?

Jan Hudec
la source

Réponses:

6

MISE À JOUR - cette réponse, même si elle semblait avoir un sens pour moi et pour les autres, se révèle largement erronée (et suffisamment erronée en ce qui concerne l'intention, comme étant effectivement tout simplement fausse). Étant donné que (comme indiqué dans un commentaire par AProgrammer), il n'est pas autorisé d'utiliser le SCU en dehors des constantes de chaîne lorsque le même caractère peut être représenté normalement dans le jeu de caractères de base. Donc, ne l'utilisez pas pour échapper aux mots clés, comme dans mon exemple; et pas l'utiliser pour faire des "identifiants" comme 23skiddoen échappant à la2. Il pourrait encore être utilisé pour rendre les noms compatibles avec les langues externes, je suppose, mais seulement, semble-t-il, lorsque ces noms commencent par une lettre ou un caractère étendu et ne contiennent que des lettres, des chiffres, du soulignement et des caractères étendus - qui semble beaucoup trop restrictif pour soutenir correctement cette intention. Il doit donc être que l'intention principale est (comme dans la réponse d'Aprogrammer) d'autoriser ces caractères supplémentaires dans les identificateurs et d'activer les éditeurs source où ces caractères sont affichés graphiquement, tout en permettant au fichier source d'être en ASCII ordinaire.


Les programmes C ++ peuvent appeler des fonctions écrites dans d'autres langages. C'est une bonne stratégie de la part du comité de normalisation de s'assurer que C ++ sera interopérable avec d'autres langages qui peuvent autoriser des caractères non alphanumériques ou unicode dans les noms de fonction, même si ces langages n'existent pas encore. La norme n'a pas besoin de spécifier comment cela fonctionnera au niveau de l'éditeur de liens, etc; mais il est bon d'avoir un mécanisme spécifié en place pour le permettre.

Vous n'avez pas besoin de regarder vers l'avenir pour voir une utilisation pour cela. Supposons que j'ai une ancienne bibliothèque C avec une fonction appelée catch(ou protégée, ou mutable) ... et je veux l'appeler à partir de C ++. Et pour une raison quelconque, je ne peux pas ou ne veux pas modifier le code C (Au fait, j'ai dû plus d'une fois gérer un ancien code C qui utilisait un nom de fonction devenu un mot-clé C ++ ...)

Avec les noms UC, je peux écrire ceci dans un en-tête, puis appeler simplement 'catch_func ()':

extern "C" {
       int catc\u0068( int a, int b );  // C 'catch()' function
}
inline int catch_func( int a, int b ) { return catc\u0068(a,b); }

Bien sûr, c'est moche, mais cela n'a pas d'importance car il n'est qu'à un seul endroit dans l'en-tête. La même approche pourrait être utilisée pour créer des stubs pour appeler des fonctions dans d'autres langages, et fonctionne même si les noms sont des mots clés C ++ ou unicode, ou ont des espaces .ou d'autres signes de ponctuation intégrés

Diverses autres langues ont des dispositifs permettant la création d'identifiants qui ne suivent pas le modèle général; par exemple dans Verilog, \abcdest un identifiant équivalent à abcd, mais \whileet \23skidooet \44.e2sont également des identifiants, qui ont besoin du préfixe antislash pour être vus comme tels. En raison de la manière dont Verilog est utilisé, il est important d'autoriser tous les noms, lorsqu'ils se rapportent à des interfaces externes.

greggo
la source
Cas d'utilisation intéressant. Bien que je soupçonne (lorsque cela est possible), il serait plus agréable d'écrire un petit fichier C pour traduire le nom (et donc d'utiliser l'identifiant C ++) et de demander à C ++ d'appeler cette fonction C.
Thomas Eding
1
Vous ne pouvez pas écrire cela pour deux raisons, le premier SCU en dehors de la chaîne et les littéraux de caractères ne peuvent pas faire référence au caractère dans les ensembles de base sans rendre le programme mal informé, deuxièmement si cette clause n'était pas présente, le SCU est géré dans la phase 1 de la traduction et il n'y aurait donc pas de différence de traitement entre un UCS faisant référence à un caractère de l'ensemble de base et le caractère lui-même.
AProgrammer
4

Il permet à un système permettant aux caractères unicode dans l'identifiant d'exporter la source dans un format compilable sur n'importe quel compilateur conforme standard. IE, c'est un moyen de coder en unicode sur le jeu de caractères de base (plus ou moins comme les citations imprimables sont utilisées pour le courrier électronique, les systèmes qui savent mieux sont capables de faire un meilleur travail, d'autres systèmes fonctionnent toujours).

AProgrammer
la source
2

Quelqu'un peut vouloir créer un identifiant en utilisant un caractère de langue étrangère qui ne peut pas être entré sur le clavier ou le périphérique d'entrée. Alternativement, l'identifiant peut contenir un caractère qui ne peut pas être imprimé à l'aide de la police ou des capacités de sortie du périphérique, mais l'IDE souhaite afficher une représentation précise.

akton
la source
4
Dans le premier cas, l'identifiant ne ressemblerait pas à ce caractère, donc le code serait illisible et l'identifiant n'a pas vraiment d'importance pour la machine. Et pour le second, la représentation dans l'IDE est un problème complètement distinct.
Jan Hudec
1

C ++ nécessite que les caractères étendus réels apparaissant littéralement dans la source se comportent de manière identique avec les noms de caractères universels. Autoriser les noms de caractères universels dans les identificateurs permet aux programmeurs d'utiliser des caractères étendus dans les identificateurs.

bames53
la source
Si les caractères étendus réels sont pris en charge, ils doivent se comporter comme des caractères universels correspondants. Mais ils n'ont pas besoin d'être soutenus.
Jan Hudec
1
C'est vrai, mais cela manque en quelque sorte le point, qui est que si le comité veut spécifier que les implémentations prenant en charge les caractères étendus doivent prendre en charge l'utilisation de ces caractères dans les identificateurs, cela nécessite que les UCN soient autorisés dans les identificateurs. C'est-à-dire que les UCN sont autorisés dans les identificateurs, pas nécessairement parce que c'est tellement lisible et que tout le monde aime coder manuellement les noms en hexadécimal, mais parce que si la spécification veut autoriser l'utilisation de caractères étendus dans les identificateurs, elle le fait en spécifiant que les UCN sont autorisés dans les identificateurs.
bames53