8
votes

Est-il correct d'avoir une variable de fil-locale avec le même nom qu'une variable locale non thread-locale?

J'ai une variable locale de fil envPtr et la variable qui n'est pas thread-local également appelé envPtr . Cette dernière variable n'est utilisée que dans un seul fil dont le code d'exécution ne voit pas la déclaration de variable de fil-locale. La variable de fil-thread-locale est utilisée par différents threads, chacun desquels ne voit pas ni ne doit voir la déclaration de la variable locale non thread.

Ce scénario est-il possible et produit un comportement défini? J'utilise Linux 32bit et 64 bits sur X86.


3 commentaires

Avoir exemple de code de la manière dont une envPtr serait décorée avec __ thread (?), Mais une autre non? La seule façon dont je peux imaginer que ceci est des non-externes dans deux fichiers différents .. Et si oui, il semble que cela semble être responsable simplement dans ce contexte.


@pst Oui, c'est comme ça que c'est fait. Ils sont déclarés dans des fichiers CPP et une fonction env * getenv (); est fourni dans un en-tête. Chaque fichier .cpp le définit différemment. Les threads qui utilisent la version TLS exécutent sur le code à partir d'un fichier .so chargé dans le même processus que le fil principal qui utilise la variable non-TLS (qui est un compilateur JIT LLVM utilisé par une coque de repliement ).


J'ai voté pour fermer parce que je pense qu'il a une solution vraiment simple: je vais simplement utiliser un nom différent pour le fichier .CPP lié à la DLL et pour le fichier .CPP lié à l'exécutable principal. EDIT: Cela limiterait l'applicabilité des fichiers .so, alors je voudrais toujours essayer d'autres approches.


3 Réponses :


3
votes

Cela devrait fonctionner et produire un comportement correct, car les variables sont deux variables distinctes.

Je recommanderais vivement de ne pas le faire, car il ne fera que rendre le logiciel moins maintenu. Que ce comportement soit correct semble être moins important que la compréhension du code sera - à l'aide du même nom de variable pour deux ensembles de données avec un comportement très différent semble problématique.


5 commentaires

@Yakk L'auteur utilisait "OK" (que je mets dans des citations) pour faire référence à la question suivante: "Ce scénario est-il possible et produit un comportement défini?"


Je conviens que "c'est possible et produit un comportement défini". :) Mais je conseillerais fortement à éviter d'avoir des variables globales (et thread-local) nommées les mêmes que les variables locales - je suggérerais de choisir un schéma de dénomination. Ou même simplement, par convention, en le collant dans un espace de noms thread_local ou autre.


@Yakk ahh oui je vais juste le nommer différemment! Si vous le postez comme une réponse, je l'accepterai!


Qu'il s'agisse de deux variables distinctes ou non dépend de la liaison. Si le lien est externe, ils sont la même variable. (Je vais ajouter la suggestion de Yakk de les mettre dans des espaces de noms différents. Bien que le nom thread_local ne fonctionne pas pour le nom de l'espace de noms.)


@Jameskanze rire, c'est vrai. :) Alors, que diriez-vous de quelque chose comme Espace de noms virtuel ?



3
votes

De votre description, on sonne comme ils sont deux variables distinctes (ni l'une ni l'autre ombre l'autre) auquel cas il semble préfectement correct d'un point de vue technique.

Cela dit que je ne suggérerais jamais de faire cela parce que la chose la plus probable qu'elle se produise est que quelqu'un sera confus au sujet de la signification dans la maintenance future et entraînera davantage de problèmes d'essayer de comprendre le code.


1 commentaires

Qu'ils soient deux variables distinctes ou non dépend de la liaison du nom (qui n'est pas influencée par thread_local ).



4
votes

Sont-ils la même variable, ou pas? En d'autres termes, qu'est-ce que c'est Leur Linkage ?

S'il est externe, alors non. S'il est interne, alors c'est ok sauf si les deux définitions ne se produisent dans le même fichier .

S'il n'y a pas de liaison, il n'y a pas de problème. < p> sauf si j'ai oublié quelque chose, thread_local n'a aucun impact sur le lien, de sorte que les règles habituelles s'appliquent (et définissant la variable thread_local dans une unité de traduction, et non dans une autre. , est une violation de la règle d'une définition).

Je pense qu'il y a un bogue dans la norme ici, cependant. Les standard (§7.1.1 / 1) dit que "si thread_local apparaît dans n'importe quel Déclaration d'une variable Il doit être présent dans tout déclarations de cette entité. "Il n'y a pas de déclaration explicite qu'un diagnostic n'est pas requis, ou cette violation de cette règle est un comportement indéfini, un compilateur est donc requis à diagnostiquer l'erreur. Sauf que, bien sûr, si vous définissez à Portée d'espace de noms: xxx

dans une unité de traduction, et: xxx

dans une autre, le compilateur ne peut probablement pas Diagnostiquer l'erreur (Et je suis assez sûr que le comité ne voulait pas l'exiger). Je suppose que l'intention ici est un comportement indéfini.


1 commentaires

Oui, la variable était externe, malheureusement, mon idée ne fonctionnera pas. Je vais essayer d'autres approches alors.