Możesz zaimplementować domyślną new
, aby wywołać funkcję niezatwierdzoną. Następnie, w czasie łącza, dostaniesz błąd dla użytkowników gołej new
rozmowy:
#include <stdexcept>
inline void * operator new (std::size_t) throw(std::bad_alloc) {
extern void *bare_new_erroneously_called();
return bare_new_erroneously_called();
}
Kiedy testowałem go na IDEONE, mam ten błąd:
/home/geXgjE/ccrEKfzG.o: In function `main':
prog.cpp:(.text.startup+0xa): undefined reference to `bare_new_erroneously_called()'
collect2: error: ld returned 1 exit status
W moich testach, używając g++
, nie ma błędu połączenia, jeśli nie ma odniesienia do gołego new
w programie. Wynika to z faktu, że g++
nie emituje kodu dla nieużywanych funkcji inline
.
Nie mam zainstalowanego Visual Studio w moim systemie, więc poniższe informacje oparte są tylko na niektórych dokumentach, które znalazłem. Aby operator widoczny był na całym obrazie, należy umieścić jego definicję w pliku nagłówkowym, a następnie użyć w kompilatorze opcji . * Zgodnie z this answer program Visual Studio nie wygeneruje kodu dla nieużywanych funkcji inline
(takich jak g++
). Należy jednak sprawdzić, czy istnieje poziom optymalizacji, który należy włączyć dla tego zachowania, czy nie.
* g++
has a similar compiler option: -include detect_bare_new.h
.
Zakłada się, że zamierzasz przekazać własne podzielniki do szablonów C++ i klas w standardowej bibliotece C++. Jeśli nie, to inlined kod w standardowych nagłówków, które wymagają domyślnego przydzielania (który wezwie new
) spowodują błąd łączące, jak również. Jeśli chcesz zezwolić standardowej bibliotece C++ na używanie domyślnej new
, to prostym sposobem na jej działanie (kosztem dłuższego czasu kompilacji) jest dodanie wszystkich standardowych nagłówków C++, które zamierzasz umieścić na górze detect_bare_new.h
plik.
Podajesz, że przenośność rozwiązania nie jest dla ciebie ważna.Ale dla kompletności, powinienem zwrócić uwagę na kwestię poprawnie wskazaną przez Ben Voigt: Standard C++ nie gwarantuje zachowania nie generowania kodu dla nieużywanych funkcji inline
. Tak więc można uzyskać błąd połączenia, nawet jeśli funkcja nie jest używana. Ale jeśli kod nie ma innych odniesień do niezaimplementowanej funkcji, z wyjątkiem egzekucji wewnątrz kodu, to błąd ten mieściłby się w samej definicji new
. Na przykład, g++
może generować błąd jak:
/home/QixX3R/cczri4AW.o: In function `operator new(unsigned int)':
prog.cpp:(.text+0x1): undefined reference to `bare_new_erroneously_called()'
collect2: error: ld returned 1 exit status
Jeśli system to taki, który generuje kod dla niewykorzystanych inline
funkcji, można jeszcze obejścia. Obejście to zadziała, jeśli linker zgłosi wszystkie błędne odniesienia do niezdefiniowanej funkcji. W takim przypadku, jeśli jedyny zaobserwowany błąd powiązania wynika z definicji samego operatora new
, nie ma nieoczekiwanych połączeń z nagim new
. Po sprawdzeniu, że kod zawiera tylko jeden błąd, można zmienić linię łącza, aby uwzględnić obiekt lub bibliotekę, która ma odpowiednią definicję bare_new_erroneously_called()
, która spowodowałaby wyjątek środowiska wykonawczego.
Czy próbowałeś patrząc na wyjściu łącznika? Sądzę, że na podstawie danych wyjściowych mapy linkera można by stwierdzić, czy wywoływane są procedury przydzielania. Nie wskazuje na krzywdzącą linię, ale przynajmniej byłaby w stanie przerwać w czasie budowy. –
ciekawy wskaźnik tam: http://bytes.com/topic/c/answers/854450-there-any-way-disable-global-operator-new – SirDarius
czy jest to opcja do implementacji domyślnej (wszystkie formy) nowej/usunąć pod względem niestandardowego nowego? Wydaje mi się, że można wyeksportować nowe/usunąć przy użyciu pliku .def, co powoduje (cały?) Proces przy użyciu eksportowanej wersji. – stijn