C++ 结束在另一个线程中使用的对象的生存期

C++ 结束在另一个线程中使用的对象的生存期,c++,multithreading,language-lawyer,lifetime,happens-before,C++,Multithreading,Language Lawyer,Lifetime,Happens Before,关于下面的代码,标准能说些什么 #包括 #包括 #包括 int main() { 静态断言(sizeof(int)=sizeof(float)); 使用名称空间std::chrono_文本; 自动pi=新整数{10}; std::线程t([pi](){ 对于(int i=0;i

关于下面的代码,标准能说些什么

#包括
#包括
#包括
int main()
{
静态断言(sizeof(int)=sizeof(float));
使用名称空间std::chrono_文本;
自动pi=新整数{10};
std::线程t([pi](){
对于(int i=0;i<3;i++){

std::cout在计算
::new(pi)float{};
表达式后在线程中访问
*pi
,会导致未定义的行为

在相同的
[basic.expr]
部分中,显示:

程序可以通过重用对象占用的存储来结束任何对象的生命周期

一旦为
pi
指向的
int
分配的存储被重新用于存储浮点,对象
*pi
的生存期就结束了。第7段说,当线程访问该值时,您有未定义的行为

第6段中给出了一个例子,它正在做与您正在做的相同的事情,但是没有线程,并且注释它是未定义的行为

所有这些的常见结果包括线程中的循环可能会打印相同的值3次(如果它在循环之前读取
*pi
一次并显示该值),或者您可能会得到一次或两次
10
,然后得到由二进制值表示的整数,表示为-1.0f。但这些并不是唯一可能的结果

本国际标准中规定的对象和参考的特性仅适用于给定对象或参考的使用寿命

“在”一词没有正式定义,但将其定义为“在寿命开始之后和寿命结束之前”是合理的

现在,与“之后发生”相反的是“之前不发生”,它是“之前发生或与之不同步”。因此,在对象生命周期开始之前发生或与之不同步,或在对象生命周期结束之后发生或与之不同步的操作,“在其生命周期内”不会执行.如果此类操作依赖于此对象的“属性”,则其表现出未定义的行为


基于这些原因,我认为您的示例显示了未定义的行为,因为对对象的访问
*pi
与其生命周期结束时不同步。

“第7段说,当线程访问该值时,您有未定义的行为。”这是真的,但正如我在问题中所问的,这一段中的after是否意味着它适用于访问发生在生命周期结束之后的情况,而不适用于生命周期结束和访问之间没有before关系的情况?你想说在这一节中,“before”和“after”指的是“before before”关系。在本节中,“before”和“after”分别指“before”[和“before after”]关系。当然,“before”是before和“after”的缩写对于发生在之后的。我不确定我是否完全理解您的意图。我的意思是:在工作线程上访问
*pi
不会在
int
对象的生命周期结束之前发生;因此,它不会在“期间”发生该对象的生命周期;因此,标准没有定义该访问的行为;因此,该访问显示未定义的行为。请注意,“
A
不会发生在
B
之前”不要求或暗示“
A
发生在
B
之后”-两种情况都不可能在另一种之前发生。啊,现在我明白你的意思了。有道理。