0

I'm interested in the internal implementation of std::string concatenation in GCC. Specifically, suppose I want to concatenate some relatively large strings, a and b. I'm quite wary of string concatenation in general, whereas strings are immutable in a lot of high-level languages.

#include <iostream>

int main(){
  std::string a = "This would be some kind of data.";
  std::string b = "To be concatenated with this, and other things.";

  // Is building c this way equivalent to strcpy'ing a, ' ', b, and '\n' into
  // a sufficiently large chunk of memory, or are intermediate variables used
  // and discarded?
  std::string c = a + ' ' + b + '\n';
  std::cout << c;
}

Is building c this way equivalent to strcpy'ing a, ' ', b, and '\n' into a sufficiently large chunk of memory, or are intermediate variables used and discarded?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Douglas B. Staple
  • 10,510
  • 8
  • 31
  • 58
  • The content of `a` ends up being copied 3 times, you would need expression templates or at least rvalue references to do better. By the way, reading the source is a good way to know what it does... – Marc Glisse Aug 22 '14 at 15:07
  • @MarcGlisse When I get a chance I'll trawl through the GCC source code to see if I can find it. – Douglas B. Staple Aug 22 '14 at 15:26
  • https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/include/bits/basic_string.h?revision=213873&view=markup – Marc Glisse Aug 22 '14 at 15:37

1 Answers1

1

std::string c = a + ' ' + b + '\n'; will do:

std::string tmp1 = a.operator+('');
std::string tmp2 = tmp1.operator+(b);
std::string c = tmp2.operator+('\n');

http://www.cplusplus.com/reference/string/string/operator+/

Concatenate strings Returns a newly constructed string object with its value being the concatenation of the characters in lhs followed by those of rhs.

With enabled optimizations, compiler will/might remove these unnecessary copies

Or pre allocate the string manually.

std::string c;
c.reserve(a.size()+1+b.size()+1);
c += a;
c += ' ';
c += b;
c += '\n';

Now it won't create that temporary objects. Even without reserve. It won't reallocate that often (on large strings). Because buffers grow new_size=2*size (in libstdc++)

See also std::string and its automatic memory resizing

Also worth mentioning C++11 can std::move memory, see https://stackoverflow.com/a/9620055/362904

Community
  • 1
  • 1
KoKuToru
  • 4,055
  • 2
  • 20
  • 21