2013-01-23 12 views
8

Ich habe eine Thread-lokale Variable envptr und Variable, die Thread nicht lokal ist auch envptr genannt. Die letztere Variable wird nur in einem einzelnen Thread verwendet, dessen Ausführungscode die Thread-lokale Variablendeklaration nicht anzeigt. Die threadlokale Variable wird von verschiedenen Threads verwendet, von denen jeder die Deklaration der nicht threadlokalen Variablen nicht sieht oder nicht sehen muss.Ist es in Ordnung, eine thread-lokale Variable mit demselben Namen wie eine non-thread-lokale Variable zu haben?

Ist dieses Szenario möglich und erzeugt ein definiertes Verhalten? Ich benutze Linux 32bit und 64bit auf x86.

+0

Haben Sie Beispielcode, wie man 'envptr' mit' __thread' (?) Dekorieren würde, aber ein anderer nicht? Der einzige Weg, den ich mir vorstellen kann, ist nicht extern in zwei verschiedenen Dateien.und wenn, dann scheint es, als ob es einfach in diesem Zusammenhang beantwortbar wäre. –

+1

@pst ja, so ist es gemacht. Sie sind in cpp-Dateien deklariert und eine Funktion 'Env * getEnv();' wird in einer Kopfzeile bereitgestellt. Jede '.cpp' Datei definiert sie anders. Die Threads, die die TLS-Version verwenden, werden mit Code aus einer '.so'-Datei ausgeführt, die in den gleichen Prozess wie der Hauptthread geladen wird, der die Nicht-TLS-Variable verwendet (dies ist ein LLVM-JIT-Compiler, der von einer REPI-Shell verwendet wird). –

+0

Ich habe beschlossen zu schließen, weil ich denke, dass es eine wirklich einfache Lösung hat: Ich werde einfach einen anderen Namen für die .cpp-Datei verwenden, die mit der DLL und der CPP-Datei verknüpft ist. EDIT: Dies würde die Anwendbarkeit der .so-Dateien einschränken, also möchte ich noch andere Ansätze ausprobieren. –

Antwort

3

Sind sie die gleiche Variable oder nicht? Mit anderen Worten, was ist ihre linkage?

Wenn es extern ist, dann nein. Wenn es intern ist, ist es OK , es sei denn, die beiden Definitionen in der gleichen Datei auftreten.

Wenn keine Verbindung vorhanden ist, gibt es kein Problem.

Sofern ich nicht etwas übersehen habe, hat thread_local keinen Einfluss auf die Verknüpfung, so dass die üblichen Regeln gelten (und die Variable thread_local in einer Übersetzungseinheit und nicht in einer anderen definieren, ist eine Verletzung der Ein-Definition-Regel).

Ich denke, es gibt hier einen Fehler im Standard. Der Standard (§7.1.1/1) besagt, dass "Wenn thread_local in einer beliebigen Deklaration einer Variablen erscheint, muss sie in allen Deklarationen dieser Entität vorhanden sein." Es gibt keine explizite Anweisung , dass eine Diagnose nicht erforderlich ist oder dass die Verletzung dieser Regel nicht definiert ist, so dass ein Compiler den Fehler diagnostizieren muss. Abgesehen davon, dass, natürlich, wenn Sie definieren im Namespace -umfang:

thread_local int i; 

in einer Übersetzungseinheit, und:

int i; 

in einem anderen, dann ist wahrscheinlich der Compiler kann den Fehler nicht diagnostiziert (und ich bin ziemlich sicher, dass der Ausschuss es nicht verlangen wollte). Meine Vermutung ist, dass die Absicht hier ist undefiniertes Verhalten.

+1

Ja, die Variable war extern, also wird meine Idee leider nicht funktionieren. Ich werde dann andere Ansätze versuchen. –

3

Dies sollte funktionieren und korrektes Verhalten erzeugen, da die Variablen zwei verschiedene Variablen sind.

Ich würde dringend empfehlen, dies nicht zu tun, da es nur die Software weniger wartbar machen wird. Ob dieses Verhalten richtig ist oder nicht, scheint weniger wichtig zu sein, denn wie verständlich der Code sein wird - es scheint problematisch, den gleichen Variablennamen für zwei Datensätze mit sehr unterschiedlichem Verhalten zu verwenden.

+0

@pst gibt es viele gut definierten Code, der nicht "OK" ist. – Yakk

+0

@Yakk Der Autor verwendete "OK" (was ich in Anführungszeichen gesetzt habe), um auf die Frage zu verweisen: "Ist dieses Szenario möglich und erzeugt ein definiertes Verhalten?" –

+0

Ich stimme zu, dass "es möglich ist und ein definiertes Verhalten erzeugt". :) Ich würde jedoch dringend davon abraten, globale (und thread-lokale) Variablen zu verwenden, die dieselben Namen haben wie lokale Variablen - ich würde vorschlagen, ein Namensschema auszuwählen. Oder einfach nur per Konvention, indem man es in einen 'Namespace thread_local' oder was auch immer klebt. – Yakk

3

Aus Ihrer Beschreibung klingt es wie zwei verschiedene Variablen (die eine überschattet die andere nie). In diesem Fall scheint es aus technischer Sicht vollkommen ok zu sein.

Das würde ich nie vorschlagen, dies zu tun, weil die wahrscheinlichste Sache ist, dass jemand verwirrt über die Bedeutung in der zukünftigen Wartung wird und mehr Probleme verursachen wird, den Code zu verstehen.

+1

Ob zwei verschiedene Variablen sind oder nicht, hängt von der Verknüpfung des Namens ab (der nicht von 'thread_local' beeinflusst wird). –

Verwandte Themen