27

I'm wondering whether the C++ string is considered small enough to be more efficient when passed by value than by reference.

Anonymous
  • 4,167
  • 11
  • 47
  • 52
  • Why? That is, what do you hope to accomplish with this knowledge? – wallyk Dec 11 '09 at 04:31
  • possible duplicate: http://stackoverflow.com/questions/1567138/const-t-arg-vs-t-arg – Kirill V. Lyadvinsky Dec 11 '09 at 05:32
  • Although it involves time travel, I would say this should now be marked as a duplicate of [Are the days of passing const std::string & as a parameter over?](https://stackoverflow.com/questions/10231349/are-the-days-of-passing-const-stdstring-as-a-parameter-over), which is the canonical discussion of this question in terms of modern C++. – underscore_d May 23 '17 at 22:23

2 Answers2

35

No. Pass it by reference:

void foo(const std::string& pString);

In general, pass things by-reference if they have a non-trivial copy-constructor, otherwise by-value.

A string usually consists of a pointer to data, and a length counter. It may contain more or less, since it's implementation defined, but it's highly unlikely your implementation only uses one pointer.

In template code, you may as well use const T&, since the definition of the function will be available to the compiler. This means it can decide if it should be a reference or not for you. (I think)

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • 5
    Your heuristic doesn't work for `double` and `long double` (which are normally better off being passed by value). As well, for single-argument functions, it's normally better to pass 2 x machine word UDTs by value, as registers will be used to store both parts (and save an extra indirection). – Pavel Minaev Dec 11 '09 at 04:39
  • 4
    Furthermore, `sizeof(T)` is a very poor measure in general if only because it doesn't measure the true size of data that will be copied. `string` is a particularly good example of that, as `sizeof(string)` will typically be `sizeof(void*)` on a naive implementation (a simple pointer to data), or two or three words on short-string optimizing implementation. Yet, when you copy a string, its copy constructor will copy the data being pointed to, which is unaccounted for. Same goes for `vector`, and many other. – Pavel Minaev Dec 11 '09 at 04:41
  • 4
    I personally prefer the following heuristic: built-ins by value, anything that has a copy-constructor by const reference. – Matthieu M. Dec 11 '09 at 08:17
  • @GMan: :D ... unfortunately it does not account for the "pass-by-value" optimization which can help the compiler avoid copies... though it's hard to know when it'll kick in :/ – Matthieu M. Feb 14 '11 at 20:31
3

Definitely not. Unless your particular implementation has copy-on-write semantics (rare these days due to threading concerns), the whole string has to be copied when it's passed by value (even if the actual string data is stored on the heap). Even if the string object itself is only a couple of pointers internally, the amount of data to be copied is linear in the length of the string.

Drew Hall
  • 28,429
  • 12
  • 61
  • 81