Is using malloc for int undefined behavior until C++20

C++MallocUndefined BehaviorC++20

C++ Problem Overview


I was told that the following code has undefined behavior until C++20:

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

Is that true?

The argument was that the lifetime of the int object is not started before assigning the value to it (P0593R6). To fix the problem, placement new should be used:

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

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

At the same time, the code does not have undefined behavior in pure C. But, what if I allocate an int in C code and use it in C++ code?

// 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;

Is it still undefined behavior?

C++ Solutions


Solution 1 - C++

> 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.

Solution 2 - C++

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionanton_rhView Question on Stackoverflow
Solution 1 - C++BarryView Answer on Stackoverflow
Solution 2 - C++Yakk - Adam NevraumontView Answer on Stackoverflow