标签:placement-new c language-lawyer const c17
“Using placement new to update a reference member?”问题显示了这个例子(简化):
struct Foo { int& v_; };
int a, b;
Foo f{a};
new (&f) Foo{b};
assert(&f.v_ == &a); // UB
通过其原始名称访问f绝对是UB作为explained by T.C. in the linked question.我知道std :: launder可用于解决此问题:
assert(&std::launder(&f)->v_ == &a); // OK, will fire the assert
但是使用placement new返回的指针怎么样?即
auto p = new (&f) Foo{b};
assert(&(p->v_) == &a); // UB? OK?
在这种情况下,我们不是通过其原始名称引用对象,而是通过返回的任何放置.
这是未定义的行为还是标准所允许的?
解决方法:
这个:
auto p = new (&f) Foo{b};
assert(&(p->v_) == &a); // UB? OK?
定义明确.断言将触发. new创建一个新对象,p指向该新对象.这一切都很好.我们正在重用f的存储,并且在[basic.life]中有很多规则关于什么是好的而不是关于如何使用旧名称的规则 – 有关于如何使用f的规则,以前指针指向f等等.你不能重复使用而不洗涤它.有关在这种情况下如何以及何时可以调用析构函数的规则,或者如何重用存储用于静态存储或const对象 – 这些都不重要.
但是p是一个新东西 – 它只是指新对象.并且p-> v_是新的int&你创建的那个引用了b.这与a不是同一个对象,因此指针比较不相等.
标签:placement-new,c,language-lawyer,const,c17 来源: https://codeday.me/bug/20190827/1746049.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。