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.
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. –
@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). –
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. –