In the following C 98 statement:
multiThreadService[nextBuffer] = new (NULL) MultiThreadService(binder);
Would it be correct to say:
- this is "placement new",
- the object will be created (at NULL, somehow?) and thrown away, and
multiThreadService[nextBuffer]
will now be NULL?
I was also told this could be UB - is that the case?
CodePudding user response:
First, it is not necessarily calling the global non-allocating placement-new operator new
overload void* operator new(std::size_t size, void* ptr)
(What is commonly meant by "placement new".)
Because the new-expression is not qualified as ::new
, it may prefer an in-class overload of operator new
if a suitable one exists and furthermore the type of NULL
is not void*
, but either std::nullptr_t
or an integral type (the former not being possible in C 98). Therefore there are some potential alternative results of overload resolution even in the global case.
Searching the project for operator new
overloads one can find at least one possible candidate at https://github.com/aneto0/MARTe2/blob/master/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h#L85, which seems to return a valid pointer even if the placement argument (second function argument) is a null pointer.
If the selected overload is really the global non-allocating placement-new operator new
, then it was basically a noop in C 98 resulting in a null pointer. new
expressions were required to not do any initialization if operator new
returns a null pointer.
However this was changed with CWG 1748 and now the behavior is undefined if the global non-allocating placement-new operator new
returns a null pointer value. This may have been considered a defect against C 98 as well (I don't know), in which case -std=c 98
will not prevent the undefined behavior on a current compiler.