Вы можете реализовать по умолчанию new
, чтобы вызвать нереализованную функцию. Затем, во время компоновки, вы получите сообщение об ошибке для пользователей голого new
вызова:
#include <stdexcept>
inline void * operator new (std::size_t) throw(std::bad_alloc) {
extern void *bare_new_erroneously_called();
return bare_new_erroneously_called();
}
Когда я тестировал на IDEONE, я получил эту ошибку:
/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
В моих тестах, используя g++
, нет ошибки ссылки, если в программе нет ссылок на голый new
. Это связано с тем, что g++
не испускает код для неиспользованных функций inline
.
У меня нет Visual Studio, установленной в моей системе, поэтому следующая информация основана только на некоторой документации, которую я нашел. Чтобы заставить оператора inline new
увидеть всюду, вы должны поместить его определение в файл заголовка, а затем использовать опцию /FI detect_bare_new.h
в своем компиляторе. * Согласно this answer, Visual Studio не будет генерировать код для неиспользованных inline
функций (например, g++
). Однако вы должны проверить, есть ли уровень оптимизации, который должен быть включен для этого поведения или нет.
* g++
has a similar compiler option: -include detect_bare_new.h
.
Предполагается, что вы намерены передать свои собственные распределители шаблонам и классам C++ в стандартной библиотеке C++. Если вы этого не сделаете, то встроенный код в стандартных заголовках, которые вызывают распределитель по умолчанию (который вызовет new
), также вызовет ошибку связывания. Если вы хотите, чтобы стандартная библиотека C++ использовала по умолчанию new
, тогда простой способ заставить ее работать (за счет более длительных времени компиляции) - добавить все стандартные заголовки C++, которые вы собираетесь включить в начало detect_bare_new.h
файл.
Вы заявляете, что переносимость решения для вас не важна.Но для полноты, я должен подчеркнуть вопрос, который Бен Фойгт правильно указывает: стандарт C++ не гарантирует поведение не генерирующего кода для неиспользуемых функций inline
. Таким образом, можно получить ошибку связывания, даже если функция не используется. Но, если код не имеет других ссылок на нереализованную функцию, кроме только в пределах заштрихованной реализации new
, ошибка будет в самом определении new
. Например, g++
может генерировать ошибку, как:
/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
Если ваша система один, который генерирует код для неиспользуемых inline
функций, вы можете все еще есть обходной путь. Обходной путь будет работать, если компоновщик сообщит все ошибочные ссылки на неопределенную функцию. В этом случае, если наблюдаемая единственная ошибка связывания связана с определением самого оператора new
, неожиданных звонков на голой new
нет. После проверки того, что код имеет только одну ошибку, вы могли бы изменить линию ссылок, чтобы включить объект или библиотеку, у которой есть соответствующее определение bare_new_erroneously_called()
, которое будет генерировать исключение во время выполнения.
Вы пробовали смотреть на выходе линкера? Я бы подумал, что вы сможете указать на выходе компоновщика компоновки, вызываются ли подпрограммы распределителя. Это не указывает на оскорбительную линию, но, по крайней мере, она сможет сломать время сборки. –
интересный указатель там: http://bytes.com/topic/c/answers/854450-there-any-way-disable-global-operator-new – SirDarius
- это возможность реализовать стандартные (все формы) новые/удалить с точки зрения вашего нового? Кажется, я помню, что можно экспортировать new/delete с помощью .def-файла, в результате чего (весь?) Процесс используется с экспортированной версией. – stijn