Programmatically determine if std::string uses Copy-On-Write (COW) mechanism

两盒软妹~` 提交于 2019-12-21 02:56:51

问题


Following up on the discussion from this question, I was wondering how does one using native C++ determine programmatically whether or not the std::string implementation they are using utilizes Copy-On-Write (COW)

I have the following function:

#include <iostream>
#include <string>

bool stdstring_supports_cow()
{
   //make sure the string is longer than the size of potential
   //implementation of small-string.
   std::string s1 = "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789";
   std::string s2 = s1;
   std::string s3 = s2;

   bool result1 = (&s1[0]) == (&s2[0]);
   bool result2 = (&s1[0]) == (&s3[0]);

   s2[0] = 'X';

   bool result3 = (&s1[0]) != (&s2[0]);
   bool result4 = (&s1[0]) == (&s3[0]);

   s3[0] = 'X';

   bool result5 = (&s1[0]) != (&s3[0]);

   return result1 && result2 &&
          result3 && result4 &&
          result5;
}

int main()
{
  if (stdstring_supports_cow())
      std::cout << "std::string is COW." << std::endl;
   else
      std::cout << "std::string is NOT COW." << std::endl;
   return 0;
}

The problem is I can't seem to find a C++ tool chain where it returns true. Is there a flaw in my assumption about how COW is implemented for std::string?

Update: Based on kotlinski comments, I've changed the use of writeble references to data() in the function, it now seems to return "true" for some implementations.

bool stdstring_supports_cow()
{
   //make sure the string is longer than the size of potential
   //implementation of small-string.
   std::string s1 = "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789";
   std::string s2 = s1;
   std::string s3 = s2;

   bool result1 = s1.data() == s2.data();
   bool result2 = s1.data() == s3.data();

   s2[0] = 'X';

   bool result3 = s1.data() != s2.data();
   bool result4 = s1.data() == s3.data();

   s3[0] = 'X';

   bool result5 = s1.data() != s3.data();

   return result1 && result2 &&
          result3 && result4 &&
          result5;
}

Note: According N2668: "Concurrency Modifications to Basic String", in the upcoming C++0x standard, COW option will be removed from basic_string. thanks to James and Beldaz for bringing that up.


回答1:


Using &s1[0] to take the adress is not what you want, [0] returns a writable reference and will create a copy.

Use data() instead, it returns a const char*, and your tests may pass.




回答2:


The copy-on-write paradigm is dependent on knowing when you are doing a write. This will occur whenever the object is returning a writable reference.

If you work with const references to the strings, you may be able to compare the addresses if the class was specialized to disable the copy when returning a const reference to the data.



来源:https://stackoverflow.com/questions/4496150/programmatically-determine-if-stdstring-uses-copy-on-write-cow-mechanism

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!