7
votes

Exemple d'entité déclarée dans un espace de noms anonyme qui a une liaison externe

Compte tenu des déclarations ci-dessous (mettre l'accent sur la mine) au §3.5 / 4 et dans la note [94] au § 7.3.1.1 / 1, j'aimerais disposer d'un seul exemple d'une entité déclarée dans un espace de noms non nommé qui a liaison externe.

§3.5 / 4

un espace de noms non nommé ou un espace de noms déclaré directement ou indirectement Dans un espace de noms non nommé a une liaison interne . Tous les autres espaces de noms avoir une liaison externe. un nom ayant une portée d'espace de nom qui n'a pas été Compte tenu de la liaison interne ci-dessus a le même lien que l'englobion Espace de noms s'il s'agit du nom de

  • une variable; ou
  • une fonction; ou
  • une classe nommée (clause 9), ou une classe non nommée définie dans une déclaration TypeDEF dans laquelle la classe a le nom TypeDEF pour le lien objectifs (7.1.3); ou
  • une énumération nommée (7.2), ou une énumération sans nom définie dans une déclaration TypeDEF dans laquelle l'énumération a le nom Typef pour objectifs de liaison (7.1.3); ou
  • un énumérateur appartenant à une énumération avec liaison; ou
  • Un modèle.

    note [94] sur §7.3.1.1 / 1:

    Bien que des entités dans un espace de noms non nommé puissent avoir une liaison externe, ils sont efficacement qualifiés par un nom unique à leur traduction unité et donc ne peut jamais être vu à partir d'une autre unité de traduction.


1 commentaires

Je soupçonne que la note de bas de page peut être une restes de C ++ 03, où les noms des espaces de noms non nommés avaient une liaison externe (car sinon, ils ne pouvaient pas être utilisés comme paramètres de modèle). Les auteurs ont simplement oublié de le supprimer.


3 Réponses :


0
votes

Par exemple xxx

selon la norme C ++

6 Le nom d'une fonction déclarée dans la portée du bloc et le nom d'un Variable déclarée par une liste d'externe d'une portée de blocage a un lien. Si il y a une déclaration visible d'une entité avec un lien avec le même nom et type, ignorant les entités déclarées en dehors de la plus interne Enclosser la portée de l'espace de nom, la déclaration de la portée du bloc déclare que même entité et reçoit la liaison de la déclaration précédente. Si Il y a plus d'une telle entité correspondante, le programme est mal formé. Sinon, si aucune entité correspondante n'est trouvée, la portée du bloc L'entité reçoit une liaison externe


4 commentaires

Je crois que le ou au §3.5 / 2 premier point de balle n'est pas exclusif. Donc, je ne suis pas d'accord que x a une liaison externe dans votre exemple.


@Wake Up Brésil X OS Automatica Variable déclarée avec Quakifier Extern. Donc, s'il y a une déclaration précédente de x dans l'espace de noms enfermé avec le lien, il a la même liaison.see 3.5 / 6.


§3.5 / 6 Vous vient de vous dire que le X a la même liaison que le x déclaré dans la portée des espaces de noms extern int x = 10; . Mais cela n'implique pas que ce x a une liaison externe. Voir §3.5 / 4 Point de bullet: Nom ayant une péril d'espace de noms qui n'a pas reçu de liaison interne ci-dessus a la même liaison que l'espace de noms enfermé s'il s'agit du nom de - une variable; . Voir aussi §7.1.1 / 6 qui fait référence au §3.5, concernant la liaison d'un nom déclaré avec le spécificateur extern .


@Wake Up Brésil Il semble que vous ne comprenez pas ce que vous lisez. La variable X est définie comme ayant une liaison externe dans un espace de noms non nommé. La variable locale déclenchée dans la fonction a également une liaison externe car il existe une variable avec le même nom et le même nom dans l'espace de noms enfermé. Quel est le problème?!.



1
votes

C'est une bonne question car il est difficile de démontrer. Nous pouvons tirer parti des autres règles de la norme C ++ pour montrer qu'une variable d'espace de noms anonyme peut avoir une liaison externe.

Modèle sur une liaison int * avec une liaison externe réussira tout en modélisant sur une liaison interne. P>

$ g++-4.8 main.cpp -o main
main.cpp: In function 'int main()':
main.cpp:17:30: error: '& {anonymous}::i' is not a valid template argument of
type 'int*' because '{anonymous}::i' does not have external linkage
  temp_on_extern_linked_int<&i>();
                              ^


4 commentaires

AFAIK, vous avez prouvé que l'espace de noms non nommé avait une liaison externe dans C ++ 03, et pour cette affaire, vous n'avez même pas besoin de la déclaration extern int i; , car le compilateur reconnaît la déclaration int i = 5; comme ayant une liaison externe.


Pour C ++ 11, je ne peux vous citer que la norme, mais que vous fournissez déjà la citation pertinente dans l'OP, il n'est pas clair ce que vous recherchez. Est-ce que cela aide à savoir qu'un espace de noms et les variables au sein de ne pas avoir nécessairement le même lien?


De plus, ce qui a changé en C ++ 11 qui enfreint l'exemple est des paramètres de modèle et non des règles de liaison.


En C ++ 11, le code compile parce que la déclaration extern int i; n'ajoute rien à la déclaration int i = 5; , c'est-à-dire la variable I continue d'avoir un lien interne, malgré le spécificateur extern .



5
votes

Vous regardez un défaut de la norme.

Le changement qui fait que les membres de l'espace de noms Sans nom ont une liaison interne se produisent assez tard dans le processus de normalisation C ++ 11, en novembre 2010 ( CWG Numéro 1113 ). En conséquence, un certain nombre de places dans la norme doivent être modifiées, mais n'étaient pas. Dont l'un est la note de bas de page que vous avez citée.

CWG Numéro 1603 , actuellement dans Statut "prêt" (lu: la résolution est susceptible d'être adopté lors de la prochaine réunion du comité), résoudra cela et un certain nombre d'autres problèmes liés à donner un lien interne aux membres de l'espace de noms non nommé.


1 commentaires

C'est exactement ce que je cherchais. Grande réponse (+1).