在C++20之前,对int未定义的行为使用malloc



我被告知以下代码在C++20之前都有未定义的行为:

int *p = (int*)malloc(sizeof(int));
*p = 10;

这是真的吗?

其论点是int对象的生存期在为其赋值之前没有开始(P0593R6(。要解决此问题,应使用放置new

int *p = (int*)malloc(sizeof(int));
new (p) int;
*p = 10;

我们真的必须调用一个默认构造函数来启动对象的生命周期吗?

同时,代码在纯C中没有未定义的行为。但是,如果我在C代码中分配一个int并在C++代码中使用它呢?

// C source code:
int *alloc_int(void)
{
int *p = (int*)malloc(sizeof(int));
*p = 10;
return p;
}
// C++ source code:
extern "C" int *alloc_int(void);
auto p = alloc_int();
*p = 20;

它仍然是未定义的行为吗?

这是真的吗?

是。从技术上讲,没有部分:

int *p = (int*)malloc(sizeof(int));

实际上创建了一个类型为int的对象,因此取消引用p是UB,因为那里没有实际的int

我们真的必须调用默认构造函数来启动对象的生命周期吗?

您是否必须根据C++对象模型来避免C++20之前的未定义行为?对如果你不这样做,任何编译器真的会造成伤害吗?我不知道。

[…]它仍然是未定义的行为吗?

是。在C++20之前,您仍然没有在任何地方创建int对象,所以这就是UB。

是的,是UB。列举了int存在的方式列表,但没有任何一种适用于此,除非您认为malloc是非配偶的。

它被广泛认为是标准中的一个缺陷,但重要性很低,因为C++编译器围绕UB的特定部分所做的优化不会导致该用例出现问题。

至于第二个问题,C++并没有强制要求C++和C如何交互。所以所有与C的交互都是。。。UB,也就是C++标准未定义的行为。

最新更新