关于std::launder、GCC与Clang:为何行为差异显著?
关于std::launder与placement new的GCC编译异常问题
我基于cppreference官网的std::launder示例调试时发现异常,目前无法确定是自身理解偏差引入了未定义行为(UB)、GCC存在编译器bug,还是Clang规则过松/优化过度。
具体异常情况
- doit1()场景:GCC优化时未考虑placement new的返回值,函数最终返回2,不符合预期的3;
- doit2()场景:代码逻辑合法,但GCC未生成对应执行代码;
- 上述异常在GCC多个版本(如12.1)中存在,且与优化级别相关;Clang在两种场景下表现均符合预期。
测试代码
#include <new> struct A { virtual A* transmogrify(int& i); }; struct B : A { A* transmogrify(int& i) override { i = 2; return new (this) A; } }; A* A::transmogrify(int& i) { i = 1; return new (this) B; } static_assert(sizeof(B) == sizeof(A), ""); int doit1() { A i; int n; int m; A* b_ptr = i.transmogrify(n); // std::launder(&i)->transmogrify(m); // OK, launder非冗余 // std::launder(b_ptr)->transmogrify(m); // OK, launder冗余 (b_ptr)->transmogrify(m); // KO, 本以为launder冗余,直接使用placement new返回值却出现问题 return m + n; // 预期返回3,正常情况为3,异常则为2 } int doit2() { A i; int n; int m; A* b_ptr = i.transmogrify(n); // b_ptr->transmogrify(m); // KO,同doit1的问题 static_cast<B*>(b_ptr)->transmogrify(m); // 严重异常,查看汇编可知无对应执行代码,但内存中确实存在B对象 return m + n; // 预期返回3,正常情况为3,异常则不符合预期 } int main() { return doit1(); // return doit2(); }
内容的提问来源于stack exchange,提问作者Etienne M
相关产品推荐
相关产品推荐

