2013-01-23 13 views
8

Ho una variabile locale di thread envptr e una variabile che non è thread-local anche chiamata envptr. Quest'ultima variabile viene utilizzata solo in un singolo thread il cui codice di esecuzione non visualizza la dichiarazione della variabile locale del thread. La variabile locale del thread viene utilizzata da diversi thread, ognuno dei quali non vede né ha bisogno di vedere la dichiarazione della variabile locale non thread.È OK avere una variabile locale thread con lo stesso nome di una variabile locale non thread?

Questo scenario è possibile e produce un comportamento definito? Sto usando linux 32 bit e 64 bit su x86.

+0

Avere codice di esempio di come un 'envptr' sarebbe decorato con' __thread' (?), Ma un altro no? L'unico modo in cui posso immaginare questo è non-externs in due file diversi ..e se è così, allora sembra che potrebbe rispondere semplicemente in quel contesto. –

+1

@ pst sì, è così che si fa. sono dichiarati nei file cpp e una funzione 'Env * getEnv();' è fornita in un'intestazione. Ogni file '.cpp' lo definisce diversamente. I thread che usano la versione TLS girano sul codice da un file '.so' caricato nello stesso processo del thread principale che usa la variabile non TLS (che è un compilatore JIT LLVM usato da una shell REPl). –

+0

Ho votato per chiudere perché penso che abbia una soluzione davvero semplice: userò semplicemente un nome diverso per il file .cpp collegato alla DLL e per il file .cpp collegato all'eseguibile principale. EDIT: Questo limiterebbe l'applicabilità dei file .so, quindi mi piacerebbe provare ancora altri approcci. –

risposta

3

Sono la stessa variabile o no? In altre parole, che cos'è loro linkage?

Se è esterno, quindi no. Se è interno, allora è OK a meno che le due definizioni non si verifichino entrambe nello stesso file.

Se non vi è alcun collegamento, non vi è alcun problema.

A meno che non abbia trascurato qualcosa, thread_local non ha alcun impatto sul collegamento, quindi le normali regole si applicano (e la definizione della variabile thread_local in una unità di traduzione e non in un'altra è una violazione della regola a una definizione).

Penso che ci sia un bug nello standard qui, tuttavia. Lo standard (§7.1.1/1) dice che "Se thread_local appare in una qualsiasi dichiarazione di una variabile, deve essere presente in tutte le dichiarazioni di quell'entità." Non esiste una dichiarazione esplicita che non sia necessaria una diagnostica o che la violazione di questa regola non sia definita, pertanto un compilatore è richiesto a a diagnosticare l'errore. Solo che, ovviamente, se si definisce in ambito namespace:

thread_local int i; 

in una sola unità di traduzione, e:

int i; 

in un altro, poi il compilatore probabilmente non può diagnosticare l'errore (e sono abbastanza sicuro che il comitato non volesse richiederlo). La mia ipotesi è che l'intento qui è un comportamento indefinito.

+1

Sì, la variabile era esterna, quindi purtroppo la mia idea non funzionerà. Proverò quindi altri approcci. –

3

Questo dovrebbe funzionare e produrre un comportamento corretto, poiché le variabili sono due variabili distinte.

Consiglio vivamente di non farlo, in quanto renderà il software meno manutenibile. Che questo comportamento sia corretto o meno sembra meno importante di quanto sia comprensibile il codice - l'uso dello stesso nome di variabile per due serie di dati con un comportamento molto diverso sembra problematico.

+0

@ pst c'è un sacco di codice ben definito che non è "OK". – Yakk

+0

@Yakk L'autore stava usando "OK" (che ho messo tra virgolette) per riferirsi alla domanda: "Questo scenario è possibile e produce un comportamento definito?" –

+0

Sono d'accordo che "è possibile e produce un comportamento definito". :) Ma consiglio vivamente di evitare di avere variabili globali (e thread-local) nominate come variabili locali - suggerirei di scegliere uno schema di denominazione. O anche solo, per convenzione, inserendolo in un 'namespace thread_local' o altro. – Yakk

3

Dalla tua descrizione sembra che siano due variabili distinte (nessuna delle due ombreggia l'altra), nel qual caso sembra perfetto da un punto di vista tecnico.

Ciò detto non suggerirei mai di farlo perché la cosa più probabile che accada è che qualcuno si confonderà sul significato della manutenzione futura e causerà più problemi nel cercare di capire il codice.

+1

Sia che si tratti di due variabili distinte o meno dipende dal collegamento del nome (che non è influenzato da 'thread_local'). –