Why is a string literal copied when assigning to a const std::string?
up vote
1
down vote
favorite
According to cppreference.com, when a const std::string
is constructed from an input const char*
(e.g. const std::string("some literal");
), a copy of the C string is stored in the std::string
.
I'm trying to understand if (and why) the copy is required specifically in the case where the input C string is a string literal. I would think that the std::string
could simply refer to the string literal instead of creating a copy, so that the following code would only create "some literal"
once.
std::string str1("some literal");
std::string str2("some literal");
Certainly, performing a copy for C strings that aren't string literals is wise, because it allows the std::string
to manage the lifetime of the data that it refers to. However, this is not an issue for string literals because they exist for the lifetime of the program.
Also, since we are talking about const
strings, we don't need to worry about the underlying data being changed during the program and breaking the value semantics of the std::string
s. Well, at least as long as const_cast
isn't used, but using const_cast
is asking for trouble anyway, so I'm not too worried about that case.
So, is there any reason why the compiler can't optimize this case to have const std::string
s refer to const char*
s instead of creating copies? Alternatively, if the cppreference link was incorrect, and this optimization actually is implemented by some compilers, which compilers support this?
For the sake of this question, let's assume that the string literal is long enough that the small string optimization won't be a factor.
c++ string optimization copy string-literals
add a comment |
up vote
1
down vote
favorite
According to cppreference.com, when a const std::string
is constructed from an input const char*
(e.g. const std::string("some literal");
), a copy of the C string is stored in the std::string
.
I'm trying to understand if (and why) the copy is required specifically in the case where the input C string is a string literal. I would think that the std::string
could simply refer to the string literal instead of creating a copy, so that the following code would only create "some literal"
once.
std::string str1("some literal");
std::string str2("some literal");
Certainly, performing a copy for C strings that aren't string literals is wise, because it allows the std::string
to manage the lifetime of the data that it refers to. However, this is not an issue for string literals because they exist for the lifetime of the program.
Also, since we are talking about const
strings, we don't need to worry about the underlying data being changed during the program and breaking the value semantics of the std::string
s. Well, at least as long as const_cast
isn't used, but using const_cast
is asking for trouble anyway, so I'm not too worried about that case.
So, is there any reason why the compiler can't optimize this case to have const std::string
s refer to const char*
s instead of creating copies? Alternatively, if the cppreference link was incorrect, and this optimization actually is implemented by some compilers, which compilers support this?
For the sake of this question, let's assume that the string literal is long enough that the small string optimization won't be a factor.
c++ string optimization copy string-literals
5
Allowing astd::string
to store a string literal would mean another piece of information and logic to know whether the string needs to deallocate the memory it holds on destruction. Take a look atstd::string_view
.
– tkausl
Nov 9 at 2:03
@tkausl that sounds pretty close to an answer.
– Shafik Yaghmour
Nov 9 at 5:06
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
According to cppreference.com, when a const std::string
is constructed from an input const char*
(e.g. const std::string("some literal");
), a copy of the C string is stored in the std::string
.
I'm trying to understand if (and why) the copy is required specifically in the case where the input C string is a string literal. I would think that the std::string
could simply refer to the string literal instead of creating a copy, so that the following code would only create "some literal"
once.
std::string str1("some literal");
std::string str2("some literal");
Certainly, performing a copy for C strings that aren't string literals is wise, because it allows the std::string
to manage the lifetime of the data that it refers to. However, this is not an issue for string literals because they exist for the lifetime of the program.
Also, since we are talking about const
strings, we don't need to worry about the underlying data being changed during the program and breaking the value semantics of the std::string
s. Well, at least as long as const_cast
isn't used, but using const_cast
is asking for trouble anyway, so I'm not too worried about that case.
So, is there any reason why the compiler can't optimize this case to have const std::string
s refer to const char*
s instead of creating copies? Alternatively, if the cppreference link was incorrect, and this optimization actually is implemented by some compilers, which compilers support this?
For the sake of this question, let's assume that the string literal is long enough that the small string optimization won't be a factor.
c++ string optimization copy string-literals
According to cppreference.com, when a const std::string
is constructed from an input const char*
(e.g. const std::string("some literal");
), a copy of the C string is stored in the std::string
.
I'm trying to understand if (and why) the copy is required specifically in the case where the input C string is a string literal. I would think that the std::string
could simply refer to the string literal instead of creating a copy, so that the following code would only create "some literal"
once.
std::string str1("some literal");
std::string str2("some literal");
Certainly, performing a copy for C strings that aren't string literals is wise, because it allows the std::string
to manage the lifetime of the data that it refers to. However, this is not an issue for string literals because they exist for the lifetime of the program.
Also, since we are talking about const
strings, we don't need to worry about the underlying data being changed during the program and breaking the value semantics of the std::string
s. Well, at least as long as const_cast
isn't used, but using const_cast
is asking for trouble anyway, so I'm not too worried about that case.
So, is there any reason why the compiler can't optimize this case to have const std::string
s refer to const char*
s instead of creating copies? Alternatively, if the cppreference link was incorrect, and this optimization actually is implemented by some compilers, which compilers support this?
For the sake of this question, let's assume that the string literal is long enough that the small string optimization won't be a factor.
c++ string optimization copy string-literals
c++ string optimization copy string-literals
asked Nov 9 at 1:58
Tim Johns
447112
447112
5
Allowing astd::string
to store a string literal would mean another piece of information and logic to know whether the string needs to deallocate the memory it holds on destruction. Take a look atstd::string_view
.
– tkausl
Nov 9 at 2:03
@tkausl that sounds pretty close to an answer.
– Shafik Yaghmour
Nov 9 at 5:06
add a comment |
5
Allowing astd::string
to store a string literal would mean another piece of information and logic to know whether the string needs to deallocate the memory it holds on destruction. Take a look atstd::string_view
.
– tkausl
Nov 9 at 2:03
@tkausl that sounds pretty close to an answer.
– Shafik Yaghmour
Nov 9 at 5:06
5
5
Allowing a
std::string
to store a string literal would mean another piece of information and logic to know whether the string needs to deallocate the memory it holds on destruction. Take a look at std::string_view
.– tkausl
Nov 9 at 2:03
Allowing a
std::string
to store a string literal would mean another piece of information and logic to know whether the string needs to deallocate the memory it holds on destruction. Take a look at std::string_view
.– tkausl
Nov 9 at 2:03
@tkausl that sounds pretty close to an answer.
– Shafik Yaghmour
Nov 9 at 5:06
@tkausl that sounds pretty close to an answer.
– Shafik Yaghmour
Nov 9 at 5:06
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
In your example, a std::string
simply receives a pointer, it has no way of know what kind of memory that pointer is actually pointing at.
The fact that the pointer is declared as pointing to const data is not relevant. A pointer to non-const data can be assigned to a pointer to const data (creating read-only access to otherwise writable data).
The std::string
simply has no way of knowing that the pointer it is given is pointing at a string literal. The pointer could just as easily be pointing at an array on the call stack, or to a memory block allocated with new
, or to memory owned by an external library.
There is nothing special about a narrow string literal, it is not some magic type that std::string
could adjust its behavior for. It is just a plain ordinary const char
, just one whose memory is setup by the compiler/linker. It decays to const char *
.
So std::string
does the only sane and safe thing it can do given the lack of origin info - make a copy of the data.
That also keeps the implementation simple - the std::string
always owns the data it holds.
If you want a string-like container that doesn't own the data, just points at it, then look at C++17's std::string_view
, or boost::string view
for earlier compilers.
That's fair. I was thinking that since the compiler knows that the input is a string literal, it might be capable of controlling the behavior. But I hadn't really thought through how this would be achieved.
– Tim Johns
Nov 9 at 10:56
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
In your example, a std::string
simply receives a pointer, it has no way of know what kind of memory that pointer is actually pointing at.
The fact that the pointer is declared as pointing to const data is not relevant. A pointer to non-const data can be assigned to a pointer to const data (creating read-only access to otherwise writable data).
The std::string
simply has no way of knowing that the pointer it is given is pointing at a string literal. The pointer could just as easily be pointing at an array on the call stack, or to a memory block allocated with new
, or to memory owned by an external library.
There is nothing special about a narrow string literal, it is not some magic type that std::string
could adjust its behavior for. It is just a plain ordinary const char
, just one whose memory is setup by the compiler/linker. It decays to const char *
.
So std::string
does the only sane and safe thing it can do given the lack of origin info - make a copy of the data.
That also keeps the implementation simple - the std::string
always owns the data it holds.
If you want a string-like container that doesn't own the data, just points at it, then look at C++17's std::string_view
, or boost::string view
for earlier compilers.
That's fair. I was thinking that since the compiler knows that the input is a string literal, it might be capable of controlling the behavior. But I hadn't really thought through how this would be achieved.
– Tim Johns
Nov 9 at 10:56
add a comment |
up vote
0
down vote
In your example, a std::string
simply receives a pointer, it has no way of know what kind of memory that pointer is actually pointing at.
The fact that the pointer is declared as pointing to const data is not relevant. A pointer to non-const data can be assigned to a pointer to const data (creating read-only access to otherwise writable data).
The std::string
simply has no way of knowing that the pointer it is given is pointing at a string literal. The pointer could just as easily be pointing at an array on the call stack, or to a memory block allocated with new
, or to memory owned by an external library.
There is nothing special about a narrow string literal, it is not some magic type that std::string
could adjust its behavior for. It is just a plain ordinary const char
, just one whose memory is setup by the compiler/linker. It decays to const char *
.
So std::string
does the only sane and safe thing it can do given the lack of origin info - make a copy of the data.
That also keeps the implementation simple - the std::string
always owns the data it holds.
If you want a string-like container that doesn't own the data, just points at it, then look at C++17's std::string_view
, or boost::string view
for earlier compilers.
That's fair. I was thinking that since the compiler knows that the input is a string literal, it might be capable of controlling the behavior. But I hadn't really thought through how this would be achieved.
– Tim Johns
Nov 9 at 10:56
add a comment |
up vote
0
down vote
up vote
0
down vote
In your example, a std::string
simply receives a pointer, it has no way of know what kind of memory that pointer is actually pointing at.
The fact that the pointer is declared as pointing to const data is not relevant. A pointer to non-const data can be assigned to a pointer to const data (creating read-only access to otherwise writable data).
The std::string
simply has no way of knowing that the pointer it is given is pointing at a string literal. The pointer could just as easily be pointing at an array on the call stack, or to a memory block allocated with new
, or to memory owned by an external library.
There is nothing special about a narrow string literal, it is not some magic type that std::string
could adjust its behavior for. It is just a plain ordinary const char
, just one whose memory is setup by the compiler/linker. It decays to const char *
.
So std::string
does the only sane and safe thing it can do given the lack of origin info - make a copy of the data.
That also keeps the implementation simple - the std::string
always owns the data it holds.
If you want a string-like container that doesn't own the data, just points at it, then look at C++17's std::string_view
, or boost::string view
for earlier compilers.
In your example, a std::string
simply receives a pointer, it has no way of know what kind of memory that pointer is actually pointing at.
The fact that the pointer is declared as pointing to const data is not relevant. A pointer to non-const data can be assigned to a pointer to const data (creating read-only access to otherwise writable data).
The std::string
simply has no way of knowing that the pointer it is given is pointing at a string literal. The pointer could just as easily be pointing at an array on the call stack, or to a memory block allocated with new
, or to memory owned by an external library.
There is nothing special about a narrow string literal, it is not some magic type that std::string
could adjust its behavior for. It is just a plain ordinary const char
, just one whose memory is setup by the compiler/linker. It decays to const char *
.
So std::string
does the only sane and safe thing it can do given the lack of origin info - make a copy of the data.
That also keeps the implementation simple - the std::string
always owns the data it holds.
If you want a string-like container that doesn't own the data, just points at it, then look at C++17's std::string_view
, or boost::string view
for earlier compilers.
edited Nov 9 at 6:40
answered Nov 9 at 6:34
Remy Lebeau
327k18246433
327k18246433
That's fair. I was thinking that since the compiler knows that the input is a string literal, it might be capable of controlling the behavior. But I hadn't really thought through how this would be achieved.
– Tim Johns
Nov 9 at 10:56
add a comment |
That's fair. I was thinking that since the compiler knows that the input is a string literal, it might be capable of controlling the behavior. But I hadn't really thought through how this would be achieved.
– Tim Johns
Nov 9 at 10:56
That's fair. I was thinking that since the compiler knows that the input is a string literal, it might be capable of controlling the behavior. But I hadn't really thought through how this would be achieved.
– Tim Johns
Nov 9 at 10:56
That's fair. I was thinking that since the compiler knows that the input is a string literal, it might be capable of controlling the behavior. But I hadn't really thought through how this would be achieved.
– Tim Johns
Nov 9 at 10:56
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53218788%2fwhy-is-a-string-literal-copied-when-assigning-to-a-const-stdstring%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
Allowing a
std::string
to store a string literal would mean another piece of information and logic to know whether the string needs to deallocate the memory it holds on destruction. Take a look atstd::string_view
.– tkausl
Nov 9 at 2:03
@tkausl that sounds pretty close to an answer.
– Shafik Yaghmour
Nov 9 at 5:06