gpt4 book ai didi

c++ - C++中普通类型的构造和初始化

转载 作者:可可西里 更新时间:2023-11-01 16:38:34 25 4
gpt4 key购买 nike

A trivial class是平凡可复制的,并且有一个 trivial default constructor (trivial type 要么是其中之一,要么是工作方式类似的内置类)。

you can use memcpy复制普通类型的对象,并且由于 default-initializing普通类型不会更改表示中的任何字节¹,以下代码(使用 C++20 概念)是否正确初始化传入对象的拷贝?

#include <cstdlib>
#include <cstring>

#include <new>
#include <type_traits>

template <typename T>
T* copy_trivial(T orig) requires std::is_trivial_v<T>
{
void* buf = std::aligned_alloc(alignof(T), sizeof(T));

// Note the order of these statements
std::memcpy(buf, &orig, sizeof(T));
return new(buf) T;
}

( Compiler Explorer ,提供了几个实例)

看起来这段代码可以工作,因为会有一个具有正确对象表示的初始化对象。但是,假设 初始化之后没有发生任何事情,那么对象会不会有一个indeterminate value? ²?


¹ 未在单个位置指定,但默认初始化的链接过程调用构造函数,该构造函数必须是 implicitly defined ;隐式定义的构造函数 default-initializes all the members and bases ;并且该递归在 no initialization is performed 处触底对于内置的琐碎类型。

² [expr.new]p18.1中的注释说它会,但注释是非规范的,这似乎只是非放置 new 的情况。

最佳答案

does the following code (using C++20 concepts) correctly initialize a copy of the passed-in object?

不,它没有。

它确实返回一个指向有效 T 的指针,但是标准中没有任何内容要求 T 的值是 原件

普通类型的默认初始化被称为执行“无初始化”。但这与保留该内存的当前存储空间不同:[dcl.init]/12

When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced.

请注意,它表示它保留“一个不确定值”,而不是“该内存中的相同值”。如果没有这种明确的保护,该标准不需要实现来保留内存的内容。

考虑调试构建。为了捕获错误,“未执行初始化”的情况有时会用特定字节填充未初始化的内存,以便您可以检测到何时访问未初始化的内存。只有当“不确定值”不在内存中保留当前值时,这对于实现才是合法的。

在 C++ 中无法使用另一个对象的字节拷贝来初始化一个对象。您可以对任意内存执行 memcpy,但您不能在该内存中显示一个对象来自该内存。您可以 memcpy 到现有对象中,但该对象已经被初始化(除非在创建时没有执行初始化)。

所以你能做的最好的事情就是颠倒这两个语句的顺序。

关于c++ - C++中普通类型的构造和初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51344835/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com