#include <string>
static_assert(sizeof(std::string) != sizeof(void*), "using ref-counted string");
int
main()
{
}
Demo: http://melpon.org/wandbox/permlink/P8LB79Cy6ASZlKuV
This test takes advantage of the internal workings of all of the known std::lib implementations of std::string
, and of gcc's implementation in particular.
gcc's refcounted string
consists of a single pointer to a dynamically allocated structure that holds the size, capacity, reference count, and data of the string. Scott Meyers does a nice summary of string implementations in Effective STL that was accurate in the 2001 time frame. I believe (I could be mistaken) that "implementation C" in item 15 of that book is gcc's std::string.
For short-string implementations (pretty much mandated by C++11), a string
can no longer consist of a single pointer on the stack. Scott's implementation D is our first look at a short-string implementation from that era. This is the VS/Dinkumware string
. The sizeof(string)
itself will contain some data buffer to hold string data with no allocations.
One can get a handle on what different implementations are doing with this short program:
#include <iostream>
#include <string>
int
main()
{
std::string s;
std::cout << "word size is " << sizeof(void*)/sizeof(char) << '\n';
std::cout << "sizeof string is " << sizeof(s) << '\n';
std::cout << "short string buffer is " << s.capacity() << '\n';
}
This prints out the word size, typically 4 or 8 (32 bit / 64 bit) as at least one implementation (libc++) changes its characteristics on this hardware feature. Then it prints out the sizeof(string)
which will be a multiple of word size, and then the capacity()
of an empty string
, which will be the size of the short-string buffer if it exists.
Here is a somewhat incomplete survey:
gcc/libstdc++ 4.8
word size is 8
sizeof string is 8
short string buffer is 0
gcc/libstdc++ 5.2
word size is 8
sizeof string is 32
short string buffer is 15
clang/libc++ -arch i386 OS X
word size is 4
sizeof string is 12
short string buffer is 10
clang/libc++ -arch x86_64 OS X
word size is 8
sizeof string is 24
short string buffer is 22
VS-2015
word size is 4
sizeof string is 24
short string buffer is 15
In this survey, only gcc/libstdc++ 4.8 is clearly not using a short-string optimization. And only gcc/libstdc++ 4.8 has sizeof(string) == 1 word
. And this is in fact the only implementation in this survey that is using reference counting.
All in all, this test for libstdc++'s std::string
isn't portable. But by specification it doesn't have to be. We can take advantage of the known history of gcc's development in this area. The spec (the question) says it only has to work on gcc's libstdc++.
std::string
is null-terminated? If it is, you know it conforms to C++11 requirements as per C++0x FDIS 21.4.7.1/1. – Thalassastatic_assert
on. Also, in C++98/03, it would be undefined behavior to try to access the terminator character, so it might still work even on them. – Appresseds[0]
in that answer is non-const
-qualified. – Sterrett