void* operator new(std::size_t)
Por que a definição no escopo global não causa um erro de link de definição múltipla?
Por exemplo, o código abaixo compila e executa, mas imagino que libstdc++ deva definir uma função de escopo global com o mesmo nome e assinatura, não?
// 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
A sobrecarga de função
void* operator new(std::size_t)
no escopo do namespace global tem a propriedade especial de ser uma das funções de alocação global substituíveis . Estas e as funções de desalocação global substituíveis seguem regras diferentes de qualquer outra função.Eles são definidos pela implementação C++, mas ao mesmo tempo um usuário pode substituí-los por sua própria definição em qualquer lugar do programa, caso em que a definição padrão fornecida pela implementação C++ é ignorada, imediatamente na inicialização do programa. Este comportamento é impossível para qualquer outra função.