What are two variants of global `operator delete` in C++?

Viewed 105

Sorry if I ask something trivial about C++, but I have not found an appropriate answer.

It looks like there are at least two versions of ::operator delete in C++, and in particular Clang and GCC use distinct versions, as can be demonstrated here:

#include <iostream>
#include <memory>

void operator delete(void *) noexcept { std::cout << "delete1 "; }
void operator delete(void *, std::size_t) noexcept { std::cout << "delete2 "; }

int main()
{
    auto x = std::make_shared<int>();
}

Clang prints delete1 and GCC prints delete2 ( https://gcc.godbolt.org/z/TWavo37dG ).

So if one writes a program that must be compatible with any C++ compiler then both function versions must be provided, right?

2 Answers

The standard library implementation of sized delete calls the unsized version.

Note that gcc -Wextra generates a warning if you override one and not the other.

The sized deletes:

Called instead of (1-2) if a user-defined replacement is provided, except that it's unspecified whether (1-2) or (5-6) is called when deleting objects of incomplete type and arrays of non-class and trivially-destructible class types. A memory allocator can use the given size to be more efficient.

leave freedom to the compiler about what it does in certain circumstances.

You can get clang to call the sized delete by passing -fsized-deallocation. I do not know if clang without that flag is standards compliant, nor why they require that flag to support sized deletion.

But it is at least a workaround to get similar behavior.

Related