Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the right behavior when overloading operator delete without overloading new? gcc and clang differ

The following code behaves differently with clang (version 5.0.0-3~16.04.1 on x86_64-pc-linux-gnu) and gcc (9.2.0).

void operator delete(void* ptr) noexcept {
    std::cout << "overloaded delete" << std::endl;
    free(ptr);
}

int main() {
    int* pint = new int;
    delete pint; // clang doesn't go through overloaded operator delete, gcc does
}

gcc goes via the overloaded operator delete while clang avoids it preferring the global delete.

(When adding an overloaded operator new both compilers agree and go through both overloaded versions).

Code: http://coliru.stacked-crooked.com/a/0903bd53a8c04a9b

like image 414
Amir Kirsh Avatar asked Nov 06 '22 11:11

Amir Kirsh


1 Answers

Compilers are allowed to optimize-out allocations with new and omit calls to the global replaceable operator news and operator deletes completely, even if they have side effects, see [expr.new]/10 and [expr.delete]/7.1 of the C++17 standard draft.


If you compile without the -O2 flag, you will see your message printed with both compilers and gcc trunk also omits the allocation with optimizations enabled.


If the allocation/deallocation function calls are not removed by the compiler, I would assume that your operator delete has undefined behavior, because you have no guarantee that the pointer you are being passed was allocated by malloc and calling free on it has undefined behavior if it wasn't.

You need to always replace both operator new and operator delete.

like image 191
walnut Avatar answered Nov 15 '22 11:11

walnut