小字符串优化(调试与发布模式)

Small String Optimisation (Debug vs Release mode)

本文关键字:布模式 模式 字符串 优化 调试      更新时间:2023-10-16

我一直在使用此示例脚本检查小字符串优化(在 MSVC 2019 中(:

#include <string>
void* operator new(size_t size)
{
std::printf("global op new called, size = %zun", size);
void* ptr = std::malloc(size);
if (ptr)
return ptr;
else
throw std::bad_alloc{};
}
int main()
{
std::string test = "small value";
return 0;
}

注意,我从 https://en.cppreference.com/w/cpp/memory/new/operator_new 那里拿了void* operator new(size_t size)

发布模式下,优化按预期工作(即new不会被调用(,但在调试模式下,脚本实际上打印global op new called, size = 16.向下钻取后,这似乎是由于标头xmemory中的此代码段:

#if _ITERATOR_DEBUG_LEVEL == 0
#define _GET_PROXY_ALLOCATOR(_Alty, _Al) _Fake_allocator()
template <class _Alloc>
using _Container_proxy_ptr = _Fake_proxy_ptr_impl;
#else // _ITERATOR_DEBUG_LEVEL == 0
#define _GET_PROXY_ALLOCATOR(_Alty, _Al) static_cast<_Rebind_alloc_t<_Alty, _Container_proxy>>(_Al)
template <class _Alloc>
using _Container_proxy_ptr = _Container_proxy_ptr12<_Rebind_alloc_t<_Alloc, _Container_proxy>>;
#endif // _ITERATOR_DEBUG_LEVEL == 0

我们可以看到,在发布模式下(即_ITERATOR_DEBUG_LEVEL == 0( 我们使用_Fake_proxy_ptr_impl,而在调试模式下我们使用使用new_Container_proxy_ptr12


我的问题很简单:为什么调试模式和发布模式之间存在这种差异?

小字符串优化在调试模式下仍然存在。 如果我们创建一个更大的string

std::string test = "large value.large value.large value.large value.";

然后我们得到实际的string分配

global op new called, size = 64

在调试和发布版本中。

您观察到的是用于迭代器调试的容器代理的分配(从#if _ITERATOR_DEBUG_LEVEL可以看出(

struct _Container_proxy { // store head of iterator chain and back pointer

您可以通过使用/D _ITERATOR_DEBUG_LEVEL=0构建来禁用迭代器调试(但随后它将对所有容器禁用,因此对于vectormap等也是如此(。