在 c + + 20之前使用 malloc 作为 int 未定义行为

有人告诉我下面的代码在 c + + 20之前是有未定义行为的:

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

是真的吗?

参数是,在为 int对象赋值(P0593R6)之前,不会启动 int对象的生命周期。为了解决这个问题,应该使用位置 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;

还有未定义行为吗?

6503 次浏览

Is it true?

Yes. Technically speaking, no part of:

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

actually creates an object of type int, so dereferencing p is UB since there is no actual int there.

Do we really have to call default constructor that is trivial to start the life time of the object?

Do you have to per the C++ object model to avoid undefined behavior pre-C++20? Yes. Will any compiler actually cause harm by you not doing this? Not that I'm aware of.

[...] Is it still undefined behavior?

Yes. Pre-C++20, you still didn't actually create an int object anywhere so this is UB.

Yes, it was UB. The list of ways an int can exist was enumerated, and none applies there, unless you hold that malloc is acausal.

It was widely considered a flaw in the standard, but one of low importance, because the optimizations done by C++ compilers around that particular bit of UB didn't cause problems with that use case.

As for the 2nd question, C++ does not mandate how C++ and C interact. So all interaction with C is ... UB, aka behaviour undefined by the C++ standard.