What is short/small string optimization? It’s a way to squeeze some bytes into a std::string object without actually allocating them on the heap. It’s a hackery involving C++ unions and clever space management. Say sizeof(std::string) is, oh I don’t know, 24 bytes on Mac’s LLVM? The implementation manages to squeeze 22 characters into that (not including the terminating NULL) before having to allocate on the heap. Impressive. Less impressive is GCC’s implementation on Linux, with sizeof(std::string) being 32 bytes but only 15 can be optimized before going to the heap. I used to have this number for Visual Studio’s implementation but… see the rant above 😛 The capacity of an empty string is the give away for how much you can fit in it before going to the heap 😉
Check it out yourself on your favorite compiler with the code below!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <string> using namespace std; int main() { auto size = sizeof(string); auto capacity = string().capacity(); auto small = string(capacity, '*'); auto big = string(capacity + 1, '*'); cout << "sizeof : " << size << endl; cout << "Capacity: " << capacity << endl; cout << "Small : " << small.capacity() << endl; cout << "Big : " << big.capacity() << endl; } |
sizeof : 24
Program output (LLVM on Mac).
Capacity: 22
Small : 22
Big : 31
The llvm implementation must rely on the alignment of pointers returned from malloc, so they can just use the lowest bits as flags. Clever.
By the way, you should look at the Conan package manager. It helps a lot in cross platform development.
(for the 100$ :P) => Use conan as package manager
I’ve already tried to build your examples on windows but unfortannely not all required packages are available
So you need to create the missing packages and then you can do simple the following for all systems (linux, windows, mac..etc):
1) install conan client: pip install conan
2) cd && mkdir build && cd build
3) conan install ..
4) conan build ..
I can send you my example… but don’t know where to send to, but the conanfile.py will something like:
from conans import ConanFile, CMake, tools
from conans.tools import os_info
import os
import sys
import shutil
class BlogConan(ConanFile):
settings = “os”, “compiler”, “build_type”, “arch”, “cppstd”
generators = “cmake_paths”
options = {“shared”: [True, False]}
default_options = {“shared”: False}
requires = (
“TBB/4.4.4@conan/stable”,
“range-v3/0.4.0@ericniebler/stable”,
“boost/1.69.0@conan/stable”,
“protobuf/3.6.1@bincrafters/stable”,
“mysql-connector-c/6.1.11@bincrafters/stable”,
“Catch2/2.7.0@catchorg/stable”,
“lz4/1.8.3@bincrafters/stable”,
“libcurl/7.61.1@bincrafters/stable”,
“fmt/5.3.0@bincrafters/stable”,
“cryptopp/7.0.0@bincrafters/stable”,
“botan/2.9.0@bincrafters/stable”
)
# if using conan to build then use the same cmake for packages
def build_requirements(self):
self.build_requires(“cmake_installer/3.13.0@conan/stable”)
For any doubt please ask
Nuno