将 int 放入 char 数组是否在法律上需要新的放置


似乎

有一些共识,即由于混叠规则C++,您不能随意将(int*)指向char数组。

从另一个问题 - 基于通用字符[]的存储并避免与严格混叠相关的UB - 似乎允许通过放置new(重新)使用存储。

alignas(int) char buf[sizeof(int)];
void f() {
  // turn the memory into an int: (??) from the POV of the abstract machine!
  ::new (buf) int; // is this strictly required? (aside: it's obviously a no-op)
  // access storage:
  *((int*)buf) = 42; // for this discussion, just assume the cast itself yields the correct pointer value
}

那么,上述法律C++是否真的需要新的安置才能使其合法化?

是的,放置new是必需的,否则您将违反严格的别名(分配是访问权限)。

以上合法吗?几乎(尽管它几乎适用于所有实现)。通过强制转换创建的指针不指向对象,因为(现已销毁)数组和int对象不是指针可相互转换的;使用 std::launder((int*)buf) ,或者更好的是,使用放置new 的返回值。

随着 P0593R6 引入隐式生存期类型(作为缺陷报告,因此这适用于所有C++版本),这种情况发生了变化。

alignas(int) char buf[sizeof(int)]; 开始 char 数组的生存期 char[sizeof(int)] 。这也将隐式启动您在表达式*((int*)buf) = 42中访问的int对象的生存期。

从 C++17 开始,您还需要清洗指针:*std::launder((int*)buf) = 42 .

*((int*)buf) = 42;

使用 int 左值写入int,因此首先没有混叠问题。

相关内容

最新更新