我有一個線程局部變量envptr
和非線程本地變量也稱爲envptr
。後一個變量只用於其運行代碼看不到線程局部變量聲明的單個線程。線程局部變量由不同線程使用,每個線程都看不到也不需要看到非線程局部變量的聲明。可以使用與非線程局部變量同名的線程局部變量嗎?
這種情況是否可能併產生定義的行爲?我在x86上使用linux 32位和64位。
我有一個線程局部變量envptr
和非線程本地變量也稱爲envptr
。後一個變量只用於其運行代碼看不到線程局部變量聲明的單個線程。線程局部變量由不同線程使用,每個線程都看不到也不需要看到非線程局部變量的聲明。可以使用與非線程局部變量同名的線程局部變量嗎?
這種情況是否可能併產生定義的行爲?我在x86上使用linux 32位和64位。
他們是同一個變量,還是不是?換句話說, 他們的linkage是什麼?
如果是外部的,那麼沒有。如果它是內部的,那麼它是OK ,除非兩個定義都出現在同一個文件中。
如果沒有聯繫,那麼沒有問題。
除非我忽略了某些事情,否則thread_local
對鏈接沒有影響,因此適用常規規則(並且在一個翻譯單元中定義變量thread_local
,而不是在另一個翻譯單元中違反單定義規則)。
但我認爲這裏的標準有一個缺陷。 標準(§7.1.1/ 1)說:「如果thread_local出現在變量的任何聲明中,它將出現在該實體的所有 聲明中。」沒有明確聲明 不需要診斷,或者違反此 規則是未定義的行爲,所以編譯器需要至 診斷錯誤。除此之外,當然,如果你定義在 命名空間範圍:
在thread_local int i;
一個翻譯單元,以及:
int i;
在另一個
,那麼編譯器可能無法診斷錯誤 (我相當肯定委員會不想要求它)。 我的猜測是這裏的意圖是未定義的行爲。
是的,該變量是外部的,所以不幸的是我的想法不起作用。我會嘗試其他方法。 –
這應該工作,併產生正確的行爲,因爲變量是兩個不同的變量。
我強烈建議不要這樣做,因爲它只會使軟件維護性降低。這種行爲是否正確似乎不那麼重要,因爲代碼的可理解性如何 - 對兩組具有不同行爲的數據使用相同的變量名似乎有問題。
從您的描述來看,它聽起來像是兩個截然不同的變量(兩者都不會影響其他變量),在這種情況下,從技術的角度來看似乎完全沒問題。
這就是說我永遠不會建議這樣做,因爲最有可能發生的事情是有人會對將來維護中的含義感到困惑,並會導致更多的問題,試圖理解代碼。
它們是否是兩個不同的變量取決於名稱的鏈接(不受'thread_local'影響)。 –
有一個'envptr'如何用'__thread'(?)裝飾的示例代碼,但另一個不是?我能想象得到的唯一方法是在兩個不同的文件中不存在..如果是這樣的話,那麼它似乎可能只是在這種情況下可以回答。 – 2013-01-23 18:13:15
@pst是的,這是如何做到的。它們是在cpp文件中聲明的,函數Env * getEnv();在頭文件中提供。每個'.cpp'文件都以不同的方式定義它。使用TLS版本的線程運行在'.so'文件的代碼中,該文件被加載到與使用非TLS變量(這是REPl shell使用的LLVM JIT編譯器)的主線程相同的進程中。 –
我已經投票結束了,因爲我認爲它有一個非常簡單的解決方案:我將只爲鏈接到該DLL的.cpp文件和鏈接到主可執行文件的.cpp文件使用不同的名稱。編輯:這將限制.so文件的適用性,所以我想仍嘗試其他方法。 –