Search code examples
c++undefined-behaviorplacement-new

C++ unusual use of placement new into NULL


In the following C++98 statement:

multiThreadService[nextBuffer] = new (NULL) MultiThreadService(binder);

Would it be correct to say:

  1. this is "placement new",
  2. the object will be created (at NULL, somehow?) and thrown away, and
  3. multiThreadService[nextBuffer] will now be NULL?

I was also told this could be UB - is that the case?


Solution

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