为什么C ++ 17中的全局内联变量和静态内联成员需要防护?

Joh*_*ehw 20 c++ inline c++17

从C ++ 17开始,可以使用inline关键字在标头中初始化全局变量和静态成员。虽然我了解了为什么需要保护函数中的静态变量(因为即使在多线程上下文中初始化也只应发生一次),但我不明白为什么也要保护这些新的内联变量(您可以在此处查看:https:// godbolt.org/z/YF8PeQ)。我认为无论如何,所有全局变量和静态成员的初始化都在程序执行的开始(甚至在之前main())进行,因此此时无需考虑多个线程。你能解释一下吗?

Jon*_*ely 24

包含定义并使用它的每个文件都将尝试初始化变量。即使那是串行发生的,而不是同时发生的,您仍然需要一种将变量标记为已初始化的方法,以便只有第一次出现时才会对其进行初始化,而以后尝试对其进行初始化将不会执行任何操作。

另外,main启动之前可以有多个线程。全局变量的构造函数(以及那些构造函数调用的函数)可以产生新的线程。

因此,您可以有多段代码,所有代码都在执行之前main,都尝试初始化同一变量。那就是警卫的目的。

  • 全局构造函数可以创建一个线程,该线程可以调用在不同目标文件中定义的函数,该线程可以触发该文件中定义的全局变量的初始化。C ++初始化比我想象的要复杂得多。 (5认同)
  • @JohnLettehw-另外,在`main()`启动之前运行的线程可以更改全局变量的值。在main()之前运行的构造函数可以读取全局变量的值。因此,线程在构造函数运行之前是否执行此操作很重要。 (3认同)