如果琐碎的默认构造函数不执行任何操作,为什么不能使用malloc创建琐碎的可构造对象?

Liu*_*Sha 11 c++ language-lawyer

我很难理解cppreference引用的有关普通默认构造函数的以下段落。我已经搜索了stackoverflow,但仍然没有一个明确的答案。所以请帮忙。

普通的默认构造函数是不执行任何操作的构造函数。与C语言兼容的所有数据类型(POD类型)都是默认可构造的。但是,与C语言不同,不能通过简单地重新解释适当对齐的存储来创建具有琐碎默认构造函数的对象,例如,使用std :: malloc分配的内存:正式引入新对象并避免潜在的未定义行为时需要placement-new。

具体来说,如果琐碎的默认构造函数什么都不做,为什么我们不能重新解释存储并假装存在具有给定类型的对象?您能否提供一些可能导致未定义行为的示例?

APr*_*mer 6

P0593R5给出了以下示例:

struct X { int a, b; };
X *make_x() {
  X *p = (X*)malloc(sizeof(struct X));
  p->a = 1;
  p->b = 2;
  return p;
}
Run Code Online (Sandbox Code Playgroud)

并说明:

当使用C ++编译器编译时,此代码具有未定义的行为,因为p-> a尝试写入X对象的int子对象,并且此程序从未创建X对象或int子对象。

每个[介绍对象] p1,

当隐式更改联合的活动成员或创建临时对象时,将通过定义,new-expression创建对象。

...并且该程序没有执行这些操作。

实际上,这是可行的,并且UB情况比其他任何情况都更被视为标准中的缺陷。本文的整个目标是提出一种解决该问题和类似情况而不破坏其他事物的方法。