C++标准是否要求在主线程中进行静态变量的动态初始化?
Does the C++ standard require that dynamic initialization of static variables be performed in the main thread?
C++ 标准是否要求非局部静态变量的动态初始化在调用 main()
的同一个线程中执行?
更具体地说,在 C++11 中,std::this_thread::get_id()
是否保证 return 在静态初始值设定项中和内部 main()
得到相同的结果?
编辑:
更具体地说,给出以下代码:
#include <iostream>
#include <thread>
static std::thread::id id = std::this_thread::get_id();
int main()
{
std::cout << id << "\n";
std::cout << std::this_thread::get_id() << "\n";
return 0;
}
发出的两个线程 ID required/guaranteed 匹配吗?
不,尽管以这种方式编写程序可能是个好主意。语法要求静态初始化以确定的方式发生,但不规定涉及的线程之类的事情。
没有。标准无处提供这样的保证,事实上 [basic.start.init]/p2:
暗示的恰恰相反
If a program starts a thread (30.3), the subsequent initialization of
a variable is unsequenced with respect to the initialization of a
variable defined in a different translation unit. Otherwise, the
initialization of a variable is indeterminately sequenced with respect
to the initialization of a variable defined in a different translation
unit. If a program starts a thread, the subsequent unordered
initialization of a variable is unsequenced with respect to every
other dynamic initialization. Otherwise, the unordered initialization
of a variable is indeterminately sequenced with respect to every other
dynamic initialization.
如果所有的初始化都必须在同一个线程上执行,那么在线程存在的情况下就没有必要削弱顺序保证。
标准没有说明什么线程应该执行这样的初始化。它只需要特定的顺序和保证:
3.6.2 非局部变量的初始化 [basic.start.init]
2. Static initialization shall be performed before any dynamic initialization takes place. [...] Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit. [...] If a program starts a thread, the subsequent initialization of a variable is unsequenced with respect to the initialization of a variable defined in a different translation unit. Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit.
4. It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time
after the first statement of main, it shall occur before the first odr-use of any function or variable defined in the same translation unit as the variable to be initialized.
5. It is implementation-defined whether the dynamic initialization of a non-local variable with static or thread storage duration is done before the first statement of the initial function of the thread. If the initialization is deferred to some point in time after the first statement of the initial function of the thread, it shall occur before the first odr-use of any variable with thread storage duration defined in the same translation unit as the variable to be initialized.
但是,大多数实现都会这样做 - 静态非局部变量的初始化将在调用 main()
的同一个线程中执行。来自 Visual C++ 11 的示例:
#include <iostream>
#include <thread>
using namespace std;
struct Cx
{
public:
Cx()
{
cout<<"Cx: "<<std::this_thread::get_id()<<endl;
}
};
static Cx c;
int main()
{
cout<<"Main: "<<std::this_thread::get_id()<<endl;
return 0;
}
输出:
Cx: 5820
Main: 5820
设置断点后Cx::Cx()
:
C++ 标准是否要求非局部静态变量的动态初始化在调用 main()
的同一个线程中执行?
更具体地说,在 C++11 中,std::this_thread::get_id()
是否保证 return 在静态初始值设定项中和内部 main()
得到相同的结果?
编辑:
更具体地说,给出以下代码:
#include <iostream>
#include <thread>
static std::thread::id id = std::this_thread::get_id();
int main()
{
std::cout << id << "\n";
std::cout << std::this_thread::get_id() << "\n";
return 0;
}
发出的两个线程 ID required/guaranteed 匹配吗?
不,尽管以这种方式编写程序可能是个好主意。语法要求静态初始化以确定的方式发生,但不规定涉及的线程之类的事情。
没有。标准无处提供这样的保证,事实上 [basic.start.init]/p2:
暗示的恰恰相反If a program starts a thread (30.3), the subsequent initialization of a variable is unsequenced with respect to the initialization of a variable defined in a different translation unit. Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit. If a program starts a thread, the subsequent unordered initialization of a variable is unsequenced with respect to every other dynamic initialization. Otherwise, the unordered initialization of a variable is indeterminately sequenced with respect to every other dynamic initialization.
如果所有的初始化都必须在同一个线程上执行,那么在线程存在的情况下就没有必要削弱顺序保证。
标准没有说明什么线程应该执行这样的初始化。它只需要特定的顺序和保证:
3.6.2 非局部变量的初始化 [basic.start.init]
2. Static initialization shall be performed before any dynamic initialization takes place. [...] Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit. [...] If a program starts a thread, the subsequent initialization of a variable is unsequenced with respect to the initialization of a variable defined in a different translation unit. Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit.
4. It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use of any function or variable defined in the same translation unit as the variable to be initialized.
5. It is implementation-defined whether the dynamic initialization of a non-local variable with static or thread storage duration is done before the first statement of the initial function of the thread. If the initialization is deferred to some point in time after the first statement of the initial function of the thread, it shall occur before the first odr-use of any variable with thread storage duration defined in the same translation unit as the variable to be initialized.
但是,大多数实现都会这样做 - 静态非局部变量的初始化将在调用 main()
的同一个线程中执行。来自 Visual C++ 11 的示例:
#include <iostream>
#include <thread>
using namespace std;
struct Cx
{
public:
Cx()
{
cout<<"Cx: "<<std::this_thread::get_id()<<endl;
}
};
static Cx c;
int main()
{
cout<<"Main: "<<std::this_thread::get_id()<<endl;
return 0;
}
输出:
Cx: 5820
Main: 5820
设置断点后Cx::Cx()
: