簡體   English   中英

模板類靜態成員函數中的局部靜態變量鏈接

[英]Local static variable linkage in a template class static member function

我有一個類似於內聯函數的 Local static/thread_local 變量的問題?

標准是否保證返回值始終為 1,這意味着static int x跨翻譯單元是否相同?

// TU1
template <int X>
struct C { 
  static int* f() { static int x = X; return &x; }
};

extern int* a1; 
extern int* a2; 
void sa() { a1 = C<1>::f(); a2 = C<2>::f(); }

// TU2
template <int X>
struct C { 
  static int* f() { static int x = X; return &x; }
};

extern int* b1; 
extern int* b2; 
void sb() { b1 = C<1>::f(); b2 = C<2>::f(); }

// TU3
int *a1, *a2, *b1, *b2;
void sa();
void sb();
int main() { sa(); sb(); return a1 == b1 && a2 == b2; }

標准是否保證返回值始終為 1,這意味着static int x跨翻譯單元是否相同?

標准是這樣要求的

靜態局部變量

同一內聯函數(可能是隱式內聯)的所有定義中的函數局部靜態對象都引用在一個翻譯單元中定義的同一對象。


編譯器在每個翻譯單元中生成該函數 local static 的副本,然后鏈接器選擇一個並丟棄重復項。 當涉及共享庫時,它們可能擁有自己的對象副本,但運行時鏈接器 ( ld.so ) 將所有引用解析為第一個發現的引用。 這種方法被稱為模糊鏈接

內聯函數中使用的局部靜態變量和字符串常量也被認為具有模糊鏈接,因為它們必須在函數的所有內聯和外聯實例之間共享。

在您的示例中,確實如此。 我們需要檢查[basic.def.odr] ¶6

[..] 類模板、非靜態函數模板、類模板的靜態數據成員、類模板的成員函數或未指定某些模板參數的模板特化可以有多個定義([ temp.spec], [temp.class.spec]) 在程序中,前提是每個定義出現在不同的翻譯單元中,並且定義滿足以下要求。 給定在多個翻譯單元中定義的名為 D 的實體,則

  • D 的每個定義都應由相同的記號序列組成; 和 [...]

如果 D 是一個模板並且在多個翻譯單元中定義,那么前面的要求既適用於模板定義([temp.nondep])中使用的模板封閉范圍的名稱,也適用於該點處的從屬名稱實例化 ([temp.dep])。 如果 D 的定義滿足所有這些要求,那么行為就好像只有一個 D 的定義。如果 D 的定義不滿足這些要求,那么行為是未定義的。

您的模板在這方面沒問題,就好像它們包含在同一個標​​題中一樣。 該條款中還有其他項目符號也需要保留,但它們與您的示例無關。

現在,由於您的程序中好像只有一個模板及其成員的定義,因此該靜態變量在兩個 TU 中都是相同的變量

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM