Ответ 1
Вы можете реализовать по умолчанию 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
в вашем компиляторе. * В соответствии с этим ответом Visual Studio не будет генерировать код для неиспользуемых функций inline
(например, g++
). Однако вы должны проверить, есть ли уровень оптимизации, который должен быть включен для этого поведения или нет.
*
g++
имеет аналогичную возможность компиляции:-include detect_bare_new.h
.
Предполагается, что вы намерены передать свои собственные распределители шаблонам и классам С++ в стандартной библиотеке С++. Если вы этого не сделаете, то встроенный код в стандартных заголовках, которые вызывают распределитель по умолчанию (который вызовет new
), также вызовет ошибку связывания. Если вы хотите, чтобы стандартная библиотека С++ использовала по умолчанию new
, тогда простой способ заставить ее работать (за счет более длительных времени компиляции) - добавить все стандартные заголовки С++, которые вы планируете включить в начало файл detect_bare_new.h
.
Вы заявляете, что переносимость решения для вас не важна. Но, ради полноты, я должен подчеркнуть, что Бен Фойгт правильно указывает: стандарт С++ не гарантирует поведение не генерирующего кода для неиспользуемых функций 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
, у вас может быть временное решение. Обходной путь будет работать, если компоновщик сообщит все ошибочные ссылки на функцию undefined. В этом случае, если наблюдаемая единственная ошибка связывания связана с определением самого оператора new
, неожиданных вызовов голых new
нет. После проверки того, что код имеет только одну ошибку, вы могли бы изменить линию ссылок, чтобы включить объект или библиотеку, которая имеет соответствующее определение bare_new_erroneously_called()
, которое приведет к исключению среды выполнения.