Why doesn't defining global `void operator new(std::size size)` cause multiple definition link error?

Why doesn’t defining void* operator new(std::size_t) at the global scope cause a multiple definition link error?

E.g. the code below compiles and runs, but I imagine that libstdc++ must define a global-scoped function with the same name and signature, no?

// main.cpp

#include <iostream>
#include <new>

void* operator new(std::size_t size) {
    std::cout << "Custom new called for size: " << size << " bytes" << std::endl;

    // Call malloc to allocate memory.
    void* ptr = std::malloc(size);

    return ptr;
}

int main() {
    int* p = new int;
    double* q = new double[10];

    delete p;
    delete[] q;

    return 0;
}
$ g++ --version && g++ -g ./main.cpp && ./a.out
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Custom new called for size: 4 bytes
Custom new called for size: 80 bytes

>Solution :

The function overload void* operator new(std::size_t) in the global namespace scope has the special property that it is one of the replaceable global allocation functions. These and the replaceable global deallocation functions follow different rules than any other function.

They are defined by the C++ implementation, but at the same time a user is allowed to replace them with their own definition anywhere in the program, in which case the default definition provided the C++ implementation is ignored, immediately at program startup. This behavior is impossible for any other function.

Leave a Reply