После некоторого исследования то, что @ bart-jan написал в своем втором ответе (который сейчас удален, хотя никто не проголосовал за него), на самом деле является правильным.
Как легко видеть, мой оператор вообще не вызывается в Release, вместо этого вызывается версия CRT. (И нет, для всех тех, кто стрелял в темноте, здесь нет рекурсии.) Вопрос «почему?»
Выше было скомпилировано с динамически связанным CRT (который используется по умолчанию). Microsoft обеспечивает создание экземпляра std :: string (среди многих других стандартных шаблонов) в DLL-библиотеке CRT. Просмотр заголовков Dinkumware, поставляемых с VS2005:
#if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
template class _CRTIMP2_PURE allocator<char>;
// ...
template class _CRTIMP2_PURE basic_string<char, char_traits<char>,
allocator<char> >;
Где _CRTIMP2_PURE
расширяется до __declspec(dllimport)
. Это означает, что в Release компоновщик связывает std::string
с версией, которая была создана при создании CRT, которая использует реализацию по умолчанию new
.
Непонятно, почему этого не происходит при отладке. Как правильно понял @Violet Giraffe, некоторые переключатели должны повлиять на него. Однако я думаю, что это переключатели компоновщика, а не переключатели компилятора. Я не могу найти, какой именно переключатель имеет значение.
Другой левый вопрос, который все здесь игнорировали, это "это стандарт"? Пробуя код в VS2010, он действительно называется моим operator new
независимо от того, какую конфигурацию я компилирую! Поиск в заголовках, поставляемых с VS2010, показывает, что Dinkumware удалил __declspec(dllimport)
для вышеупомянутой реализации. Таким образом, я считаю, что старое поведение действительно является ошибкой компилятора, а не стандарт.