Je suis nouveau sur C et en regardant l’arbre source de Go , j’ai trouvé ceci:
https://code.google.com/p/go/source/browse/src/pkg/runtime/race.c
void runtime∕race·Read(int32 goid, void *addr, void *pc); void runtime∕race·Write(int32 goid, void *addr, void *pc); void runtime·raceinit(void) { // ... }
Que signifient les barres obliques et les points (·)? Est-ce valide C?
MISE À JOUR IMPORTANTE:
La réponse ultime est certainement celle de Russ Cox , l’un des auteurs de Go, figurant sur la liste de diffusion golang-nuts. Cela dit, je laisse certaines de mes notes précédentes ci-dessous, elles pourraient aider à comprendre certaines choses.
De plus, à la lecture de cette réponse liée ci-dessus, je pense que le “pseudo-slash” peut maintenant être traduit en normal
/
slash aussi (comme le middot est traduit en point) dans les versions plus récentes du compilateur Go C que celle que j’ai testée ci-dessous – mais je n’ai pas le temps de vérifier.
Le fichier est compilé par le compilateur C interne de Go Language Suite , qui provient du compilateur Plan 9 C (1) (2) et présente quelques différences (principalement des extensions, AFAIK) par rapport à la norme C.
L’une des extensions est qu’il autorise les caractères UTF-8 dans les identificateurs.
Désormais, dans le compilateur C de Go Language Suite, le caractère middot (·) est traité de manière spéciale, car il est traduit en un point standard (.) Dans les fichiers object, qui est interprété par l’éditeur de liens interne de Go Language Suite comme séparateur d’espaces de noms. personnage.
Exemple
Pour le fichier suivant
example.c
(remarque: il doit être enregistré au format UTF-8 sans nomenclature):void · Bar1 () {} void foo · bar2 () {} void foo baz · bar3 () {}le compilateur C interne produit les symboles suivants:
$ go tool 8c example.c $ go outil nm exemple.8 T "" .Bar1 T foo.bar2 T foo ∕ baz.bar3Maintenant, veuillez noter que j’ai donné à
·Bar1()
unB
majuscule. C’est ainsi que je peux le rendre visible dans le code Go normal, car il est traduit exactement dans le même symbole que celui résultant de la compilation du code Go suivant:exemple de paquet func Bar1 () {} // nm affichera: T "" .Bar1
Maintenant, en ce qui concerne les fonctions que vous avez nommées dans la question, l’histoire va plus loin dans le terrier du lapin. Je suis un peu moins sûr d’être ici, mais je vais essayer d’expliquer en fonction de ce que je sais. Ainsi, chaque phrase située au-dessous de ce point doit être lue comme si elle avait ” AFAIK ” écrit juste à la fin.
La prochaine pièce manquante pour mieux comprendre ce puzzle est donc d’en savoir plus sur l’étrange ""
espace de noms et sur la façon dont l’éditeur de liens de la suite Go le gère. L’espace de noms ""
est ce que nous pourrions appeler un espace de noms “vide” (car ""
pour un programmeur signifie “une chaîne vide”), ou peut-être mieux, un espace de noms “espace réservé”. Et quand l’éditeur de liens voit une importation se dérouler comme ceci:
import examp "path/to/package/example" //... func main() { examp.Bar1() }
ensuite, il prend le fichier de bibliothèque $GOPATH/pkg/.../example.a
et, pendant la phase d’importation, substitue à la volée chaque ""
avec le path/to/package/example
. Alors maintenant, dans le programme lié, nous verrons un symbole comme celui-ci:
T chemin / vers / package / exemple.Bar1
Le caractère “·” est \xB7
selon ma console Javascript. Le caractère “” est \x2215
.
Le point relevant de l’ annexe D de la norme C99 répertorie les caractères spéciaux valides comme identificateurs dans la source C. La barre oblique ne semble pas, alors je suppose qu’elle est utilisée comme quelque chose d’autre (peut-être un espacement de nom) via une magie #define ou du préprocesseur.
Cela expliquerait pourquoi le point est présent dans la définition de la fonction réelle, mais pas la barre oblique.
Edit: Cochez cette réponse pour plus d’informations. Il est possible que la barre oblique unicode soit simplement autorisée par la mise en œuvre de GCC.
Il semble que ce ne soit pas la norme C, ni C99. En particulier, gcc
et clang
plaignent du point, même en mode C99.
Ce code source est compilé par la suite de compilateurs de la partie 9 (en particulier ./pkg/tool/darwin_amd64/6c sous OS X), qui est initialisée par le système de construction Go. Selon ce document , au bas de la page 8, Plan 9 et son compilateur n’utilisent pas du tout l’ASCII, mais utilisent plutôt Unicode. Au bas de la page 9, il est indiqué que tout caractère avec un sharepoint code suffisamment élevé est considéré comme valide pour une utilisation dans un nom d’identifiant.
Il n’y a pas de magie de pré-traitement – la définition des fonctions ne correspond pas à la déclaration des fonctions simplement parce que ce sont des fonctions différentes. Par exemple, void runtime∕race·Initialize();
est une fonction externe dont la définition apparaît dans ./src/pkg/runtime/race/race.go; Il en va de même pour la void runtime∕race·MapShadow(…)
à void runtime∕race·MapShadow(…)
.
La fonction qui apparaît plus tard, void runtime·raceinit(void)
est une fonction complètement différente, ce qui est caractéristique du fait qu’elle appelle en réalité le runtime∕race·Initialize();
.
Le compilateur / runtime go est compilé à l’aide des compilateurs C développés à l’origine pour plan9. Lorsque vous comstackz go from source, il comstackra d’abord les compilateurs plan9, puis les utilisera pour comstackr Go.
Les compilateurs plan9 prennent en charge les noms de fonction unicode [1] et les développeurs de Go utilisent des caractères unicode dans leurs noms de fonction comme pseudo-espaces de nom.
[1] Il semble que cela puisse être conforme aux normes: nom de variable unicode g ++ mais gcc ne prend pas en charge les noms de fonction / variable unicode.