【问题标题】:What are the changes, if any, to the memcpy lifetime initalization rules in the new standard?新标准中的 memcpy 生命周期初始化规则有哪些变化(如果有)?
【发布时间】:2023-03-27 03:05:01
【问题描述】:

据我所知,memcpy 进入未初始化的存储空间 cannot 可以安全地用于创建源对象的副本。

然而,在this thread 去年的 open-std WG21 "ub" 列表中,参与者引用了新的 memcpy 生命周期启动规则

这似乎没有上升到错误报告的级别,但它可能 与新的 memcpy 生命周期启动规则相关。他们会吗 为源字节和目标字节赋予某种静态类型?

根据问题的上下文和少量类型擦除示例代码,似乎它可能与通过memcpyaligned_storage 中创建新对象有关。

尽我所能搜索,我找不到对新规则的引用。我特别好奇它们是否仅适用于替换已创建对象的内容,或者它们是否改变了在未初始化内存中可能创建对象的情况。

【问题讨论】:

    标签: c++ language-lawyer c++17 memcpy object-lifetime


    【解决方案1】:

    措辞有所改变,但总体思路保持不变。来自intro.object

    object 由定义创建,new-expression 在隐式更改联合的活动成员时,或在创建临时对象时([ conv.rval],[class.temporary])。

    这些是唯一在 C++ 中创建对象的四种方法。 memcpy 不属于这四个条件中的任何一个,因此它现在(以前也从未)创建生命周期(可以通过 via = only 隐式更改联合的活动成员,而不是通过 memcpy)。

    这句话是指假设的未来对标准的改变,这将使memcpy 在某些情况下具有这种能力。今年早些时候也有关于这个主题的very long thread

    【讨论】:

    【解决方案2】:

    C++20 中的措辞有了更多变化。更改基于p0593r6,它追溯适用于自 C++98 以来的所有版本,因此尽管措辞恰好出现在 C++20 规范中,但对于 C++17 以及对于C++98等

    来自intro.object

    1. C++ 程序中的构造创建、销毁、引用、访问和操作对象。对象由定义、new 表达式、通过隐式创建对象的操作创建(见下文)...

    ...

    1. 进一步,在指定区域内隐式创建对象后 存储,一些操作被描述为产生一个指向 合适的创建对象。这些操作选择其中之一 隐式创建的对象,其地址是起始地址 的存储区域,并产生一个指针值,指向 该对象,如果该值将导致程序已定义 行为。如果没有这样的指针值会给程序定义 行为,程序的行为是未定义的。如果多个这样 指针值会给程序定义的行为,它是 未指定生成哪个指针值。

    另见this SO answer

    【讨论】:

    • @DavisHerring 好吧,修改基于p0593r6,它追溯应用于自 C++98 以来的所有版本 - 将此澄清添加到答案中。
    • 对不起,我措辞不好。确实,它是 DR,并且编译器将在他们采取任何实际行动的范围内将其应用于所有语言版本(即使这超出了 DR 的正式权力)。但是,问题是关于 C++17(已发布)中据称包含的更改,因此区分实际发生的情况很重要(您现在已经完成了!)。
    猜你喜欢
    • 2015-03-22
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    相关资源
    最近更新 更多