访问静态的内联函数

inline functions accessing static?

本文关键字:函数 静态 访问      更新时间:2023-10-16

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]静态数据成员的初始化(和任何相关的副作用)不会发生,除非静态数据成员本身以需要存在静态数据成员定义的方式使用。

所以模板类的静态成员在使用前总是初始化的。

上述所有问题都受到静态初始化顺序失败的影响,前面提到的"首次使用时构造"解决了这个问题。