C++标准是否要求在调用main()
的同一线程中执行非局部静态变量的动态初始化
更具体地说,在C++11中,是否保证std::this_thread::get_id()
在静态初始化器和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匹配?
发布于 2015-04-21 23:19:16
标准没有说明什么线程应该执行这样的初始化。它只需要特定的顺序和保证:
3.6.2非局部变量 basic.start.init的初始化
2.在进行任何动态初始化之前,应执行静态初始化。..。在单个翻译单元中定义的有序初始化的变量应按照其在翻译单元中的定义顺序进行初始化。..。如果程序启动线程,则变量的后续初始化相对于在不同翻译单元中定义的变量的初始化是无序的。否则,变量的初始化相对于在不同翻译单元中定义的变量的初始化被不确定地排序。
4.它是由实现定义的,在main的第一条语句之前,是否对具有静态存储持续时间的非局部变量进行动态初始化。如果将初始化推迟到第一条main语句之后的某个时间点,则应在第一次odr使用与要初始化的变量相同的转换单元中定义的任何函数或变量之前进行。
5.它是由实现定义的,在线程的初始函数的第一个语句之前,动态初始化具有静态或线程存储持续时间的非局部变量。如果初始化被推迟到线程的初始函数的第一条语句之后的某个时间点,则应在首次odr使用任何具有线程存储持续时间的变量之前进行,该变量与要初始化的变量在相同的翻译单元中定义。
然而,大多数实现都会这样做-静态非局部变量的初始化将在调用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()
内部设置断点之后
发布于 2015-04-21 23:14:53
不是的。标准没有提供这样的保证,事实上basic.start.init/p2暗示了相反的情况:
如果程序启动线程(30.3),则变量的后续初始化相对于在不同翻译单元中定义的变量的初始化是无序的。否则,变量的初始化相对于在不同翻译单元中定义的变量的初始化被不确定地排序。如果程序启动线程,则变量的后续无序初始化相对于其他动态初始化是无序的。否则,变量的无序初始化相对于每个其他动态初始化都是不确定的。
如果所有初始化都必须在同一线程上执行,则在存在线程的情况下不需要削弱排序保证。
发布于 2015-04-21 23:08:46
不,尽管这样写你的程序可能是个好主意。该语法要求静态初始化以确定性的方式发生,但并不规定所涉及的线程等内容。
https://stackoverflow.com/questions/29775826
复制相似问题