2020年5月15日

[C++] inline Variable and thread_local in C++17

inline variable 最大的用意應該就是允許在 header 就把變數的宣告 + 定義一次搞定吧。在 C++17 前除了少數特例 (比方說 literal type),基本上 header 只能放宣告,明確的定義是必須要放在單一的 translation unit 以遵守 ODR (one definition rule)。
直接看個例子比較快:
class MyClass {
    inline static std::string msg{"OK"}; // OK since C++17
                                         // compile-time ERROR (before C++17)
    ...
};
inline MyClass myGlobalObj; // OK even if included/defined by multiple CPP files (C++17)
                            // Link ERROR if included by multiple CPP files (before C++17)
正如上面的程式碼所示,現在可以一次在 header 把 declaration + definition 搞定,再也不用看到 declaration 後還要去找他的 definition 在哪。

當然,這並不代表當一個被放在 header 中的 inline variable 被引入到多個 cpp 檔時就會有多個實體,他依然只會有一個實體。以上面的例子來說,myGlobalObj 永遠只會有一個,就算在不同的 cpp 檔去存取這個變數,都會抓到同一個。

而在 C++17 後,inline + static constexpr 的組合蹦出了新滋味:
struct MyStruct {
    inline static constexpr int x = 5;
    static constexpr int y = 5; // y implies x since C++17
};
static constexpr 在 C++17 後等同於 inline static constexpr

最後是當 thread_local 這個 keyword 跟 inline variable 混在一起用後,效果是會讓每個 thread 都有一份自己的實體 (就是 thread_local 的效用),只是每個 thread 都只會有一份 (inline variable 的作用)。

從 C++11 之後,C++14 跟 C++17 其實有不少語言方面的設定都是這類為了讓程式寫起來更方便且提升可讀性,inline variable 也算是這個類別的吧

沒有留言:

張貼留言