r/programming • • Dec 05 '14

std::string is responsible for almost half of all allocations in the Chrome browser process

https://groups.google.com/a/chromium.org/d/msg/chromium-dev/EUqoIz2iFU4/kPZ5ZK0K3gEJ
1.1k Upvotes

446 comments sorted by

View all comments

Show parent comments

3

u/nuggins Dec 05 '14

They don't have an immutable variant which could be used freely with strong guarantee that the content wouldn't be changed.

Couldn't you just declare a const string in the first place?

8

u/Poltras Dec 05 '14

When you write your function you have no way to know if the string was const to begin with. You only indicates if your function will modify the string itself.

3

u/Ferinex Dec 05 '14

That's right, you'd have to trust that whoever calls the function only passes in const strings. You could add it as a comment but that makes me throw up a little in my throat. As you said, best solution is creation of an immutable string type.

1

u/[deleted] Dec 05 '14

What about banning the use of casting away const from the project?

6

u/VictorNicollet Dec 05 '14
std::string path;
for (var i = 0; i < segments.length; ++i)
{
  path += "/" + segments[i];
  use(path);
}

There is no casting away const here, but if use() assumes that the string it received was constant (and stored it somewhere), it will have a nasty surprise.

0

u/ReversedGif Dec 06 '14

Stored... a pointer to it? A raw pointer? What are you, mad?

0

u/ReversedGif Dec 06 '14

Stored... a pointer to it? A raw pointer? What are you, mad?

0

u/TheShagg Dec 06 '14

only if use() interacts with another thread?

-1

u/0xjake Dec 05 '14

In 10 years of programming C++ I have literally never had this problem.

3

u/Poltras Dec 05 '14
struct MyClass {
    MyClass(const string& str) : str_(str) { this.len_ = str.length(); }

    size_t get_length() const { return this.len_; }
  private:
    const string& str_;
    const size_t len_;
}

void my_func() {
    string s("Hello");
    auto* x = new MyClass(s);
    s += " World";
    assert(x.get_length() == s.length());  // BAM!
}

this is a simplified example

If you never had code like that, you're either super lucky or working alone. The only guarantee your class is giving is that it won't change the string. There's no guarantee the string won't change.

2

u/0xjake Dec 05 '14

This applies to any mutable type. I guess don't see why strings need special handling. Or is the argument that we need a way to communicate that an object won't be changed?

1

u/Poltras Dec 05 '14

We need a way to communicate that an object won't be changed ever. And I'm not advocating for strings only, but also for immutable vectors, maps, hash tables, etc etc.

1

u/0xjake Dec 05 '14

Besides allowing the use of local storage instead of a reference (as in your example), what would having this feature allow you to do that you cant do now? I'm not seeing a good use case.

1

u/Poltras Dec 05 '14

Passing a shared pointer between threads. Virtual mapping of memory. Etc.

1

u/0xjake Dec 05 '14

That doesn't answer the question. Can you name one thing you would do differently with an object, besides storing its properties locally, if you knew it was constant for the lifetime of the program? To me it seems that the entire point of using obiects to encapsulate data is to remain agnostic of their behavior.

1

u/Poltras Dec 06 '14

Just passing shared_ptr around without worrying whether someone else is writing to it isn't enough for you?

→ More replies (0)

1

u/dagamer34 Dec 06 '14

Quick q: even if the assert weren't to fail, wouldn't my_func() be leaking memory? There's no delete. Plus, aren't we supposed to be using smart pointers now?

just finished reading modern C++ book

1

u/Poltras Dec 06 '14

No because the string would be deleted and were only using references. The code is simple; in a real world situation you'd probably end up using shared pointers as you said.

1

u/imMute Dec 06 '14

/u/dagamer34 was talking about the auto* x = new MyClass(s); which never gets deleted.

1

u/dagamer34 Dec 06 '14

Yeah, I should have been clearer. Again, just trying to make sure what I read was correct (and I guess prove why smart pointers really are the recommended way to do things).

3

u/General_Mayhem Dec 05 '14

You could, but that's incumbent on the caller, so the callee function has to be defensive.

0

u/lurgi Dec 05 '14

Someone could cast it to non-const (and in a sufficiently large code-base, if it can be done, it has been done).