Section 16.4 of C++ FAQs (2nd Edition) (Paperback) by Marshall P. Cline, Greg Lomow说,内联函数不能安全地访问静态数据成员,因为可以在初始化静态数据成员之前调用该函数。

我看不到为什么这适用于内联函数,而不仅适用于其他转换单元中调用另一个转换单元中的静态数据成员的任何函数?我看不到“内联”在这场灾难中起什么作用?

最佳答案

在执行同一转换单元(或多或少的cpp文件)中的任何函数之前,static变量已完全初始化。如果main位于不同的翻译单元中,则不能保证在调用main之前对其进行初始化。 inline函数是重复的,每个翻译单元都有自己的拷贝。这意味着与static变量不同的转换单元中的内联函数可能会在正确初始化之前尝试对该变量进行读/写操作,从而导致未定义的行为。 (规则非常复杂,但这就是我所记得的)







据我所知,内联函数实际上没有比非内联函数更危险。在不同TU中访问静态函数的任何函数都是有风险的,并且由于inline恰好将函数放入每个TU中,因此大多数函数都不安全。一种解决方法是使用"construct on first use idiom"

隐式模板特化很复杂,但是出于完整性考虑:



因此,模板类的静态成员始终在使用前进行初始化。

以上所有内容均受the static initialization order fiasco约束,上述“首次使用idom构造”可解决该问题。

10-02 06:48
查看更多