GCC 4.x / C++11中std::string是否是引用计数的?

35

在使用gcc 4配合 -std=c++0x-std=c++11时,std::string是否采用引用计数?


2
我相信C++11引入了一些要求,使得写时复制变得不可能,因此消除了对引用计数的需求,但我不记得在哪里听说过这个。 - Mark Ransom
3
如果你能证明这一点(例如通过头文件或GCC邮件列表讨论等),那么你应该写一个答案而不是评论,这样你就可以得到赞了 ;) - Joseph Garvin
1
我认为有一个宏可以设置以获取非引用计数的字符串,类似于 FULLY_DYNAMIC_STRINGS。库维护者不愿意切换的原因是这会破坏与早期编译代码的二进制兼容性。 - Kerrek SB
@KerrekSB 我认为 "fully dynamic strings" 标志是指 小字符串优化 和其他避免堆内存的优化。 - Drew Dormann
1
@DrewDormann:嗯,也许吧,但GCC从来没有过小字符串优化。不过我得再确认一下。 - Kerrek SB
显示剩余2条评论
3个回答

25

C++11增加了特定的语言禁止std::string进行引用计数。 因此,如果存在这种情况,则GCC的C++11标准库存在相当大的缺陷。


12
你应该添加引用来使其更有权威性。 - Joseph Garvin
@JosephGarvin:我可以引用一些语言,说明C++11无法使用引用计数,但我没有C++98/03规范来引用使引用计数成为可能的原始语言。我不知道具体发生了什么变化;我只知道哪些规则使其目前不可能。 - Nicol Bolas
7
这可能作为一个参考或至少理由:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2534.html - Cubbi

25

查看libstdc++文档后我发现(更多信息请参见链接):

一个字符串长成这样:

                       [_Rep]
                       _M_length
[basic_string<char>]   _M_capacity
_M_dataplus            _M_refcount
_M_p ----------------> unnamed array of char_type

是的,它是引用计数的。此外,来自这里的讨论中提到:

是的,std::string最终会成为非引用计数的,但由于非引用计数的字符串在C++98中也是有效的,所以一个选择是在-std=c++98和-std=c++11模式下都切换到非引用计数的字符串。我不是说一定会发生这种情况,但这是可行的。

所以,似乎有计划将其改为符合要求(尽管我不知道进展如何)。

更新 正如emsr在评论中指出的那样,目前有一个名为vstring.h的非引用计数扩展,似乎唯一的原因是因为ABI兼容性问题,它尚未替换std::string。关于此问题有一个SO问题,在这里


2
这是libstdc++维护者之间已知的缺陷。修复它将涉及破坏ABI并引起很多麻烦。作为扩展,我们有遵守C++11 <string>要求的versa字符串[链接](http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01602.html),因为它不会引用计数。在某个时候,我们将决定通过此和其他几个C++11更改来破坏ABI。 - emsr
1
实际上,versa_string是一个包装器,可以采用多种表示方式。其中一种是引用计数字符串,另一种是短字符串优化版本。 - emsr
@emsr:谢谢你提供的信息。我还在 Stack Overflow 上找到了一个相关问题,并将其添加到我的答案中。 - Jesse Good
1
@emsr:这是否意味着当处于C++11模式时,他们撤销了所有ABI破坏性更改?GCC维基仍然表示存在破坏性:http://gcc.gnu.org/wiki/Cxx11AbiCompatibility - Joseph Garvin
@JosephGarvin:我相信List::_M_size已经被还原了,但我确定剩下的ABI破坏仍然存在。我建议按照Wiki上的检查说明进行操作。 - emsr

13

补充一些最新的信息。

std::string不再使用引用计数,以满足C++11的要求。这是在GCC 5发布时实现的。

参考https://gcc.gnu.org/gcc-5/changes.html

默认启用了新的std::string实现,使用小字符串优化而不是复制写引用计数。


2
一个复杂的问题是,尽管gcc开发人员将新的std::string实现设置为g++ 5.1的默认值,但Fedora 22(最早包含g++ 5.1的Linux发行版之一)选择将默认值设置回引用计数字符串。要在Fedora 22上获得非引用计数字符串,请使用-D_GLIBCXX_USE_CXX11_ABI=1进行构建。有关更多详细信息,请参见此处。此外,对于类似于原始帖子的其他查询,我在此处提供了一个有用的摘要表。 - dmr195

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接