测试 libstdc++ 的版本是否使用 C++11-compliant std::string
Test whether libstdc++'s version uses a C++11-compliant std::string
我正在编写一些 C++11 代码,这些代码对 std::string
的性质做出假设是有效的,但表示在 C++11 中更改的行为。在早期,libstdc++ 的 basic_string
实现符合 98/03 要求,但不符合更严格的 C++11 要求。
据我了解,libstdc++ 已经修复了 basic_string
周围的问题。问题是人们使用的许多版本的库都没有实现此修复。我的代码可能会以许多令人不快的方式默默地失败。
如果用户试图针对那些不一致的 libstdc++ 版本编译我的库,我希望 static_assert
触发。如何检测版本,同样重要的是,我应该查找哪个版本?
在 GCC 5 (Runtime Library Section of the changelog) 中引入了新的 C++11 兼容 std::string
以及新的(双)ABI。
宏_GLIBCXX_USE_CXX11_ABI
决定是使用旧的还是新的ABI,所以检查一下:
#if _GLIBCXX_USE_CXX11_ABI
当然,这仅适用于 libstdc++。
#include <string>
static_assert(sizeof(std::string) != sizeof(void*), "using ref-counted string");
int
main()
{
}
演示:http://melpon.org/wandbox/permlink/P8LB79Cy6ASZlKuV
此测试利用了 std::string
的所有已知 std::lib 实现的内部工作原理,尤其是 gcc 的实现。
gcc 的 refcounted string
由指向动态分配结构的单个指针组成,该结构包含字符串的大小、容量、引用计数和数据。 Scott Meyers 在 Effective STL 中对字符串实现进行了很好的总结,该总结在 2001 年的时间范围内是准确的。我相信(我可能会弄错)那本书第 15 项中的 "implementation C" 是 gcc 的 std::string.
对于短字符串实现(C++11 几乎强制要求),string
不能再由堆栈上的单个指针组成。 Scott 的实现 D 是我们第一次看到那个时代的短字符串实现。这是VS/Dinkumwarestring
。 sizeof(string)
本身将包含一些数据缓冲区来保存没有分配的字符串数据。
你可以了解不同的实现正在用这个简短的程序做什么:
#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';
}
这会打印出字长,通常为 4 或 8(32 位/64 位),因为至少一个实现 (libc++) 更改了其在该硬件功能上的特性。然后它打印出 sizeof(string)
,它将是单词大小的倍数,然后是空 string
的 capacity()
,如果存在,它将是短字符串缓冲区的大小.
这里有一份不完整的调查:
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
在这次调查中,只有 gcc/libstdc++ 4.8 显然没有使用短字符串优化。而且只有 gcc/libstdc++ 4.8 有 sizeof(string) == 1 word
。这实际上是本次调查中唯一使用引用计数的实现。
总而言之,这个针对 libstdc++ 的 std::string
的测试不可移植。但根据规范,它不一定是。我们可以利用已知的 gcc 在这方面的发展历史。规范(问题)说它只需要在 gcc 的 libstdc++ 上工作。
我正在编写一些 C++11 代码,这些代码对 std::string
的性质做出假设是有效的,但表示在 C++11 中更改的行为。在早期,libstdc++ 的 basic_string
实现符合 98/03 要求,但不符合更严格的 C++11 要求。
据我了解,libstdc++ 已经修复了 basic_string
周围的问题。问题是人们使用的许多版本的库都没有实现此修复。我的代码可能会以许多令人不快的方式默默地失败。
如果用户试图针对那些不一致的 libstdc++ 版本编译我的库,我希望 static_assert
触发。如何检测版本,同样重要的是,我应该查找哪个版本?
在 GCC 5 (Runtime Library Section of the changelog) 中引入了新的 C++11 兼容 std::string
以及新的(双)ABI。
宏_GLIBCXX_USE_CXX11_ABI
决定是使用旧的还是新的ABI,所以检查一下:
#if _GLIBCXX_USE_CXX11_ABI
当然,这仅适用于 libstdc++。
#include <string>
static_assert(sizeof(std::string) != sizeof(void*), "using ref-counted string");
int
main()
{
}
演示:http://melpon.org/wandbox/permlink/P8LB79Cy6ASZlKuV
此测试利用了 std::string
的所有已知 std::lib 实现的内部工作原理,尤其是 gcc 的实现。
gcc 的 refcounted string
由指向动态分配结构的单个指针组成,该结构包含字符串的大小、容量、引用计数和数据。 Scott Meyers 在 Effective STL 中对字符串实现进行了很好的总结,该总结在 2001 年的时间范围内是准确的。我相信(我可能会弄错)那本书第 15 项中的 "implementation C" 是 gcc 的 std::string.
对于短字符串实现(C++11 几乎强制要求),string
不能再由堆栈上的单个指针组成。 Scott 的实现 D 是我们第一次看到那个时代的短字符串实现。这是VS/Dinkumwarestring
。 sizeof(string)
本身将包含一些数据缓冲区来保存没有分配的字符串数据。
你可以了解不同的实现正在用这个简短的程序做什么:
#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';
}
这会打印出字长,通常为 4 或 8(32 位/64 位),因为至少一个实现 (libc++) 更改了其在该硬件功能上的特性。然后它打印出 sizeof(string)
,它将是单词大小的倍数,然后是空 string
的 capacity()
,如果存在,它将是短字符串缓冲区的大小.
这里有一份不完整的调查:
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
在这次调查中,只有 gcc/libstdc++ 4.8 显然没有使用短字符串优化。而且只有 gcc/libstdc++ 4.8 有 sizeof(string) == 1 word
。这实际上是本次调查中唯一使用引用计数的实现。
总而言之,这个针对 libstdc++ 的 std::string
的测试不可移植。但根据规范,它不一定是。我们可以利用已知的 gcc 在这方面的发展历史。规范(问题)说它只需要在 gcc 的 libstdc++ 上工作。