You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:37:08