1
votes

I know that in C/C++, if you write a string literal, this is actually placed into read-only memory with static (lifetime of the program) storage. So, for example:

void foo(const char* string) {
    std::cout << static_cast<void const*>(string) << std::endl;
}

int main() {
    foo("Hello World");
}

should print out a pointer to someplace in read-only memory.

Here's my question, let's say I want to write a copy-on-write String class which has an optimization for static data like this. Instead of copying the whole string into dynamically-allocated memory (which is expensive), why not just keep a pointer to the static data instead. Then, if a write actually does need to occur, then I can make a copy at that point.

But how can I tell if a string is static or something like:

int main() {
    char[] myString = "Hello World";
    foo(myString);
}

In this case, myString is located in the stack and not the heap, thus it's lifetime is not static.

My first thought was a special constructor for std::string_view, but I'm not sure that std::string_view implies a string with static lifetime either...

1
The storage specifier is not part of an objects type. There is no way to know from a pointer where it points to unless you know detail about the implementation where it would store pointers for different durations. - NathanOliver
@273K Now it will. The typo wasn't interesting and it was easier to fix than to write a comment. - Yakk - Adam Nevraumont
Many companies try this. The problem that occurs, it's slow. That is because of memory locality (cache) and other underlying issues (have experienced some benchmarking). In sort, nowadays memory is less expensive and it's worth way more to store it where the processor (L1 cache) expects it than to store it in random memory locations, even if it takes more memory. - lorro

1 Answers

5
votes

The easiest way I can think of is to do it with a user-defined literal operator.

struct cow_string { /* stuff */ };

cow_string operator "" _cow( const char*, size_t );

Then, when someone does:

cow_string betsy = "moo"_cow;

the argument to operator""_cow is guaranteed to be a static string. I mean, barring pathological cases like someone invoking operator"" directly by name (which I honestly don't even know if it is possible; if it is and you do it and it breaks stuff, well, you deserve whatever happens).