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

同一存储空间中混合不同隐式生存期类型对象是否合法?

C++隐式对象创建规则:同一存储区混合不同类型对象的合法性问题

为实现支持不同简单隐式生存期类型对象的内存池,需要明确:C++的隐式对象创建规则是否允许在同一存储空间内,混合存放不重叠的不同类型对象?

以下是问题示例(为便于阅读省略了安全检查与释放逻辑):

// 两种对齐方式不同的隐式生存期类型
using first_t = std::int16_t;
using second_t = std::int64_t;

#define DYNAMIC

int main() {
    static constexpr std::size_t Size = 10000;
    static constexpr std::size_t NbFirst = 3;
    static constexpr std::size_t NbSecond = 2;
#ifdef DYNAMIC
    auto* storage = new std::byte[Size];
#else
    alignas(first_t) std::byte storage[Size];
#endif

    // 在storage位置获取隐式创建的first_t数组
    auto* p_first = std::launder(reinterpret_cast<first_t*>(storage));

    // 计算剩余存储位置
    std::byte* ptr = storage + NbFirst * sizeof(first_t);
    void* p{ptr};
    std::size_t space{Size - NbFirst * sizeof(first_t)};

    // 为第二种类型寻找合适的对齐位置
    std::align(alignof(second_t), NbSecond * sizeof(second_t), p, space);

    // 在该位置获取隐式创建的second_t数组:这个数组是否合法存在?
    auto* p_second = std::launder(reinterpret_cast<second_t*>(p));

    for (std::size_t i = 0; i < NbFirst; ++i) {
        p_first[i] = static_cast<first_t>(i);
    }
    for (std::size_t i = 0; i < NbSecond; ++i) {
        p_second[i] = static_cast<second_t>(i);
    }
}

当前C++标准在[intro.object#13]至[intro.object#16]中定义了隐式对象创建规则,但对部分措辞的解读存在疑问:

疑问1:关于[intro.object#13]的表述

If multiple such sets of objects would give the program defined behavior, it is unspecified which such set of objects is created.

这句话是否意味着只会创建其中一组可能的对象?

疑问2:关于[intro.object#14]和[intro.object#16]的位置约束

These operations select one of the implicitly-created objects whose address is the address of the start of the region of storage, and produce a pointer value that points to that object, if that value would result in the program having defined behavior.

对象是否只能在触发隐式创建操作的起始位置(比如示例中的storage)创建?还是说只要满足对齐等定义良好行为的约束,就可以在存储区域内的任意位置创建?

我倾向于第二种解读,但仍不确定混合不同类型的可行性。因此想明确:上述代码模式是否合法?若不合法,原因是什么?

补充思考:如果该模式不合法,可在第二个位置使用std::start_lifetime_as(若不可用则使用基于std::memmove的实现)作为替代方案。最佳实践应是不依赖隐式对象创建,而是系统性地显式启动对象生存期。

内容的提问来源于stack exchange,提问作者Oersted

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 17:53:08