2013-01-23 68 views
8

我有一個線程局部變量envptr和非線程本地變量也稱爲envptr。後一個變量只用於其運行代碼看不到線程局部變量聲明的單個線程。線程局部變量由不同線程使用,每個線程都看不到也不需要看到非線程局部變量的聲明。可以使用與非線程局部變量同名的線程局部變量嗎?

這種情況是否可能併產生定義的行爲?我在x86上使用linux 32位和64位。

+0

有一個'envptr'如何用'__thread'(?)裝飾的示例代碼,但另一個不是?我能想象得到的唯一方法是在兩個不同的文件中不存在..如果是這樣的話,那麼它似乎可能只是在這種情況下可以回答。 – 2013-01-23 18:13:15

+1

@pst是的,這是如何做到的。它們是在cpp文件中聲明的,函數Env * getEnv();在頭文件中提供。每個'.cpp'文件都以不同的方式定義它。使用TLS版本的線程運行在'.so'文件的代碼中,該文件被加載到與使用非TLS變量(這是REPl shell使用的LLVM JIT編譯器)的主線程相同的進程中。 –

+0

我已經投票結束了,因爲我認爲它有一個非常簡單的解決方案:我將只爲鏈接到該DLL的.cpp文件和鏈接到主可執行文件的.cpp文件使用不同的名稱。編輯:這將限制.so文件的適用性,所以我想仍嘗試其他方法。 –

回答

3

他們是同一個變量,還是不是?換句話說, 他們的linkage是什麼?

如果是外部的,那麼沒有。如果它是內部的,那麼它是OK ,除非兩個定義都出現在同一個文件中。

如果沒有聯繫,那麼沒有問題。

除非我忽略了某些事情,否則thread_local對鏈接沒有影響,因此適用常規規則(並且在一個翻譯單元中定義變量thread_local,而不是在另一個翻譯單元中違反單定義規則)。

但我認爲這裏的標準有一個缺陷。 標準(§7.1.1/ 1)說:「如果thread_local出現在變量的任何聲明中,它將出現在該實體的所有 聲明中。」沒有明確聲明 不需要診斷,或者違反此 規則是未定義的行爲,所以編譯器需要至 診斷錯誤。除此之外,當然,如果你定義在 命名空間範圍:

thread_local int i; 

一個翻譯單元,以及:

int i; 
在另一個

,那麼編譯器可能無法診斷錯誤 (我相當肯定委員會不想要求它)。 我的猜測是這裏的意圖是未定義的行爲。

+1

是的,該變量是外部的,所以不幸的是我的想法不起作用。我會嘗試其他方法。 –

3

這應該工作,併產生正確的行爲,因爲變量是兩個不同的變量。

我強烈建議不要這樣做,因爲它只會使軟件維護性降低。這種行爲是否正確似乎不那麼重要,因爲代碼的可理解性如何 - 對兩組具有不同行爲的數據使用相同的變量名似乎有問題。

+0

@pst有很多明確定義的代碼不是「OK」。 – Yakk

+0

@Yakk作者正在使用「確定」(我把它放在引號中)引用問題:「這種情況是否可能併產生定義的行爲?」 – 2013-01-23 18:09:15

+0

我同意「這是可能的,併產生定義的行爲」。 :)但我強烈建議避免將全局變量(和線程局部變量)命名爲局部變量 - 我建議選擇一個命名方案。甚至按照慣例,只要將它粘貼到'namespace thread_local'或其他任何東西中即可。 – Yakk

3

從您的描述來看,它聽起來像是兩個截然不同的變量(兩者都不會影響其他變量),在這種情況下,從技術的角度來看似乎完全沒問題。

這就是說我永遠不會建議這樣做,因爲最有可能發生的事情是有人會對將來維護中的含義感到困惑,並會導致更多的問題,試圖理解代碼。

+1

它們是否是兩個不同的變量取決於名稱的鏈接(不受'thread_local'影響)。 –