访问静态的内联函数
inline functions accessing static?
Marshall p . Cline编写的c++ faq(第二版)(平装版)第16.4节指出,内联函数不能安全地访问静态数据成员,因为可以在静态数据成员初始化之前调用该函数。
我不明白为什么这适用于内联函数,而不仅仅是其他翻译单元中调用另一个翻译单元中的静态数据成员的任何函数?我不明白"内联"在这场灾难中扮演了什么角色?
static
变量在同一翻译单元 (cpp文件或多或少)中的任何函数执行之前都被完全初始化。如果main
在不同的翻译单元中,它们不能保证在main
被调用之前被初始化。inline
函数是复制的,其中每个翻译单元都有自己的副本。这意味着与static
变量不同翻译单元中的内联函数可能会在正确初始化该变量之前尝试对其进行读写,从而导致未定义的行为。(规则很复杂,但这是我记得的)
具有静态存储时间的非局部变量的动态初始化是否在main的第一个语句之前完成,这是由实现定义的。如果初始化延迟到main语句第一个语句之后的某个时间点,则初始化应发生在与待初始化变量在同一翻译单元中定义的任何函数或变量第一次使用(3.2)之前。
和
据我所知,§3.2/3一个内联函数应该定义在每一个翻译单元中,在这个翻译单元中它被经常使用。
内联函数并不比非内联函数更危险。任何访问不同TU中的静态的函数都是有风险的,并且由于inline
恰好将函数放在每个 TU中,因此大多数函数都不安全。一种变通方法是使用"首次使用时构造"的习惯用法。
隐式模板特化很复杂,但为了完整:
§14.7.1/3 [temp.inst]静态数据成员的初始化(和任何相关的副作用)不会发生,除非静态数据成员本身以需要存在静态数据成员定义的方式使用。
所以模板类的静态成员在使用前总是初始化的。
上述所有问题都受到静态初始化顺序失败的影响,前面提到的"首次使用时构造"解决了这个问题。
相关文章:
- enable_if转换构造函数(静态强制转换,is_base_of)
- 声明和定义函数静态会产生"undefined reference to function_name()"
- 有没有一种方法可以使全局函数/静态成员函数一次可呼出
- C++ - 模板类 -> 静态函数 -> 静态函数指针的链接错误
- 获取 llvm::函数静态地址
- 成员函数静态变量与成员变量
- 如何将sqlite3+扩展函数静态链接到C/C++应用程序中
- Visual Studio 2015 Natvis如何显示函数静态变量
- 返回一个指向函数静态数据的指针合适吗
- 如何将函数静态应用于非类型模板包的各个元素并对结果求和
- 是否可以通过编程方式创建函数静态对象
- 函数静态变量析构函数和线程
- 函数静态成员变量
- 隐藏模板化的辅助函数——静态成员或未命名的命名空间
- 这个解决方案对MSVC的双重检查锁定错误和函数静态有什么问题?
- 类成员函数静态和私有
- c++函数静态局部,性能好
- 函数静态变量初始化
- 使用基类中的函数静态地调用纯虚函数的派生类实现
- 使成员函数静态会使程序无法编译。想不通为什么