在琐碎的可复制结构之间使用类型双关语会有多邪恶



我有一个带有Swift接口的库,它隐藏了一个C++层。在C++中,我有struct A { ...}。我希望Swift按值传递这个结构的副本(由于各种复杂的原因(。Swift理解C声明,但不理解C++,所以我需要为它声明一些相同大小的伪C结构,例如struct FakeA { char data[/* size of A */]; }。然后,我可以使用打字双关语来来回切换。由于A通常是可复制的,我认为这没关系。然而,在cppreference.com上,它指出,"然而,与C不同,具有普通默认构造函数的对象不能通过简单地重新解释适当对齐的存储来创建,例如用std::malloc分配的内存:需要placement new来正式引入新对象并避免潜在的未定义行为。">

我们在谈论如何定义?比如说,当使用Clang为arm64和x86_64进行编译时,它会实际导致问题吗?

C++抽象了生存期的概念,即使对于没有构造函数的pod,C++也会用特定的术语定义对象的生存期开始和结束,这就是为什么即使知道它们的布局匹配,也不能重新解释内存中的字节。这是未定义的行为,因为这不是对象生命周期的开始。

在实践中,人们仍然使用这种UB,因为没有等效的非UB选项。

std::start_lifetime_as<T>new (p) std::byte[n](以前的std::bless(将是治疗这种疾病的完美药物(http://wg21.link/p0593)但遗憾的是,目前还没有。

最新更新